# Barcode Scan To Excel (`automation-lab/barcode-images-to-excel`) Actor

Decode public or uploaded barcode images and ZIP batches into Excel-ready inventory rows with values, formats, confidence, positions, source files, and per-image errors.

- **URL**: https://apify.com/automation-lab/barcode-images-to-excel.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Automation
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Barcode Images to Excel

Turn barcode pictures into clean inventory rows.
**Barcode Images to Excel** performs a barcode scan to Excel workflow from public image URLs, one uploaded image, or a ZIP archive of images.
It detects common 1D and 2D formats and writes one structured dataset row per decoded symbol.
The dataset can be downloaded directly as XLSX, CSV, JSON, or XML from Apify Console.

### What does Barcode Images to Excel do?

The Actor:

- downloads public barcode images with bounded retries and timeouts;
- accepts an image uploaded with Apify's file picker;
- expands a ZIP archive for batch inventory imports;
- detects multiple barcodes in one image;
- recognizes QR Code, EAN, UPC, Code 128, Code 39, Data Matrix, PDF417, Aztec, and other formats;
- records the decoded value, symbology, image index, orientation, position, and source;
- keeps optional traceability rows when no barcode is found;
- returns per-image errors without discarding successful rows from the rest of the batch.

Decoding runs inside the Actor with ZXing WebAssembly.
Images are not sent to a separate barcode-decoding service.

### Who is this barcode scan to Excel app for?

- **Warehouse teams** converting label photos into receiving or stocktake rows.
- **Inventory managers** consolidating barcode values from many image files.
- **E-commerce operators** preparing SKU, UPC, or EAN values for spreadsheet imports.
- **Quality teams** finding unreadable labels while preserving the source file and error.
- **Automation builders** feeding decoded values into Make, Zapier, Google Sheets, Airtable, or an API.
- **Developers** who need a batch barcode scan online endpoint without operating image-decoding infrastructure.

### Why use this Actor?

A phone scanner is useful for one physical label at a time.
This Actor is designed for files that already exist and for repeatable batch jobs.

It provides:

1. URL, direct upload, and ZIP input routes.
2. Spreadsheet-ready output with stable field names.
3. Multiple-symbol detection for composite images.
4. Bounded input, download, archive, and memory limits.
5. Per-image traceability rather than an unexplained empty run.
6. Native Apify scheduling, API, webhooks, integrations, and dataset exports.

### Supported barcode formats

You can leave `formats` empty to detect all supported formats or select a smaller set.
Available selectors include:

- QR Code and Micro QR Code;
- EAN-13 and EAN-8;
- UPC-A and UPC-E;
- Code 128, Code 39, Code 93, and Codabar;
- ITF;
- GS1 DataBar and DataBar Expanded;
- Data Matrix;
- PDF417;
- Aztec;
- MaxiCode;
- all linear formats or all matrix formats.

Format filtering can reduce false candidates and speed up a known workflow.

### What data does the Actor return?

| Field | Type | Meaning |
| --- | --- | --- |
| `source` | string | Original URL, upload label, or ZIP entry identifier |
| `sourceType` | string | `url`, `uploaded_file`, or `zip_entry` |
| `imageIndex` | integer | One-based position of the image in the run |
| `fileName` | string or null | File name when it can be inferred |
| `barcodeIndex` | integer or null | One-based symbol position within an image |
| `status` | string | `decoded`, `no_barcode`, or `error` |
| `symbology` | string or null | Detected format, such as `QRCode` or `EAN13` |
| `value` | string or null | Decoded barcode text |
| `confidence` | number or null | `1` for a validated decode; null without a decode |
| `error` | string or null | Download, decode, or no-barcode detail |
| `orientation` | number or null | Barcode rotation in degrees |
| `isInverted` | boolean or null | Whether reflectance is inverted |
| `position` | object or null | Four barcode corner coordinates in image pixels |
| `processedAt` | string | ISO 8601 processing timestamp |

`confidence` is deliberately binary.
ZXing returns validated decoded symbols rather than a statistical probability, so the Actor does not invent a percentage.

### How to run a barcode scan to Excel

1. Open the Actor in Apify Console.
2. Add public image URLs, upload one image, or upload a ZIP archive.
3. Optionally limit detection to the barcode formats you expect.
4. Choose the maximum images and symbols per image.
5. Click **Start**.
6. Open the run's **Dataset** tab.
7. Click **Export** and choose **Excel** or **CSV**.

The prefilled QR image is a live, working example.

### Input parameters

| Input | Required | Default | Description |
| --- | --- | --- | --- |
| `imageUrls` | conditionally | `[]` | Public HTTP(S) image URLs |
| `imageFile` | conditionally | none | One image uploaded through the file picker or its URL |
| `zipFile` | conditionally | none | ZIP archive of images uploaded through the file picker or its URL |
| `formats` | no | all formats | Barcode formats to detect |
| `maxImages` | no | `100` | Maximum images across every input route, from 1 to 500 |
| `maxBarcodesPerImage` | no | `20` | Maximum decoded symbols per image, from 1 to 255 |
| `includeImagesWithoutBarcode` | no | `true` | Emit a traceability row for images with no detected barcode |
| `requestTimeoutSecs` | no | `30` | Per-download timeout, from 5 to 120 seconds |

At least one of `imageUrls`, `imageFile`, or `zipFile` is required.

### Input example

```json
{
  "imageUrls": [
    "https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=SKU-INV-0042"
  ],
  "formats": ["QRCode"],
  "maxImages": 100,
  "maxBarcodesPerImage": 20,
  "includeImagesWithoutBarcode": true,
  "requestTimeoutSecs": 30
}
```

### Output example

This record comes from the prefilled input:

```json
{
  "source": "https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=SKU-INV-0042",
  "sourceType": "url",
  "imageIndex": 1,
  "fileName": "create-qr-code",
  "barcodeIndex": 1,
  "status": "decoded",
  "symbology": "QRCode",
  "value": "SKU-INV-0042",
  "confidence": 1,
  "error": null,
  "orientation": 0,
  "isInverted": false,
  "position": {
    "topLeft": { "x": 0, "y": 0 },
    "topRight": { "x": 219, "y": 0 },
    "bottomRight": { "x": 218, "y": 218 },
    "bottomLeft": { "x": 0, "y": 219 }
  },
  "processedAt": "2026-08-05T15:10:34.866Z"
}
```

Coordinates vary with image dimensions and detected symbol boundaries.

### How much does it cost to decode barcode images?

Pricing uses one small **Start** event plus one **Barcode row** event for each decoded or traceability row saved.
The current source configuration starts at **$0.003 per run** and **$0.002 per row on the Bronze tier**, with lower row prices on higher usage tiers.

Example source-price estimates on Bronze:

| Workload | Estimated Actor charge |
| --- | ---: |
| 1 image producing 1 row | $0.005 |
| 10 images producing 10 rows | $0.023 |
| 100 images producing 100 rows | $0.203 |

One image can contain multiple symbols and therefore produce multiple rows.
A no-barcode or error traceability row is also one Barcode row.
Apify platform usage can be billed separately according to your plan.
Always check the live pricing panel because tier eligibility and prices can change.

### ZIP batch workflow

Use `zipFile` when your inventory photos are already in a folder:

1. Put supported image files into a ZIP archive.
2. Upload the ZIP with the Actor's file picker.
3. Set `maxImages` to the batch ceiling you want.
4. Keep `includeImagesWithoutBarcode` enabled for reconciliation.
5. Export the dataset as XLSX.
6. Filter `status = decoded` for import and inspect other statuses separately.

Nested ZIP paths are accepted, while directory entries and unsupported files are ignored.

### Scheduling recurring inventory imports

Apify schedules can run the same input hourly, daily, weekly, or on a custom cron expression.
For a recurring workflow:

- point `imageUrls` or `zipFile` at public files generated by your upstream system;
- create an Apify schedule;
- connect the finished dataset to a webhook, Make, Zapier, or your own API;
- use `source`, `imageIndex`, and `value` as reconciliation keys;
- retain `status` and `error` so unreadable labels remain visible.

The Actor does not compare historical runs or maintain an inventory database.
Perform deduplication and change comparison in the downstream spreadsheet or pipeline.

### Export to Excel, Google Sheets, or a data pipeline

For Excel, use the Dataset **Export** menu and select XLSX.
For Google Sheets, connect the Apify integration or Make/Zapier and map `value`, `symbology`, `fileName`, and `status` columns.
For a custom pipeline, retrieve dataset items as JSON or CSV after the run finishes.

Keep `source` in downstream tables so staff can trace a value back to its image.

### Run through the Apify API with cURL

Replace `YOUR_APIFY_TOKEN` with a secret environment value:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~barcode-images-to-excel/runs?token=YOUR_APIFY_TOKEN&waitForFinish=120" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrls": [
      "https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=SKU-INV-0042"
    ],
    "formats": ["QRCode"]
  }'
```

Fetch dataset items using the `defaultDatasetId` returned by the run.
Do not commit API tokens to source control.

### Run with JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/barcode-images-to-excel').call({
    imageUrls: [
        'https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=SKU-INV-0042',
    ],
    formats: ['QRCode'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Run with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/barcode-images-to-excel').call(run_input={
    'imageUrls': [
        'https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=SKU-INV-0042'
    ],
    'formats': ['QRCode'],
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with Apify MCP

Add this Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/barcode-images-to-excel"
```

#### Claude Desktop setup

Add this remote server to Claude Desktop's MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/barcode-images-to-excel"
    }
  }
}
```

#### Cursor setup

In Cursor, open **Settings → Tools & MCP → New MCP Server** and use the same `https://mcp.apify.com?tools=automation-lab/barcode-images-to-excel` URL.

#### VS Code setup

In VS Code with MCP support, add an HTTP MCP server named `apify` with the same Actor-specific URL in your workspace MCP configuration.

Example prompts:

- “Decode the QR image at this public URL and return the value and format.”
- “Process these inventory label image URLs and give me CSV-ready rows.”
- “Run the barcode image batch and list every file that had no readable barcode.”

### Limits and safety

- A run accepts at most 500 images.
- Each image is limited to 15 MB.
- A downloaded ZIP is limited to 40 MB.
- Expanded ZIP image data is limited to 40 MB in total.
- Up to 255 symbols can be requested per image.
- URLs must use HTTP or HTTPS.
- Localhost, private-network addresses, credential-bearing URLs, and private DNS targets are blocked.
- Redirect targets are validated before download.
- Password-protected archives are not supported.
- SVG and PDF inputs are not image inputs; convert them to PNG or JPEG first.

These limits protect run memory and reduce accidental downloads.

### Image quality tips

For better decoding:

- keep the entire barcode and its quiet zone visible;
- avoid severe blur, glare, shadows, and perspective distortion;
- use sufficient pixel resolution;
- avoid aggressive JPEG compression;
- crop extremely large photos around the labels when possible;
- select the expected `formats` for a known label system;
- use a straight-on image for dense 1D barcodes.

The decoder tries rotations, inversion, and more intensive detection, but it cannot reconstruct missing bars or modules.

### Failure behavior

A bad URL or unreadable image does not discard successful images from the batch.
The Actor saves an `error` or `no_barcode` row when traceability is enabled.

The complete run fails with a non-zero status when:

- no input route is supplied;
- numeric limits are invalid;
- the selected format is unsupported;
- no supported images exist in the provided sources;
- Actor storage or charging fails.

Inspect the `error` field and run log before retrying.

### Legality and responsible use

Only submit images you are authorized to process.
Barcode values can contain internal inventory identifiers, URLs, contact details, or other sensitive text.
Control dataset access, token permissions, and retention according to your organization's policy.

The Actor does not look up product owners, prices, or personal information.
It only decodes symbols present in supplied images.
Public-URL access must comply with the host's terms and applicable law.

### Frequently asked questions

#### Does it create an actual Excel file?

Apify's dataset export creates XLSX directly.
The Actor stores normalized rows so you can also export CSV or JSON without rerunning image decoding.

#### Can one image contain several barcodes?

Yes.
Increase `maxBarcodesPerImage`; each detected symbol becomes its own row with the same `imageIndex` and a different `barcodeIndex`.

#### Why is confidence always 1 or null?

The decoder provides validated results, not probability scores.
`1` means a barcode was successfully decoded; null means there is no validated decode.

#### Why did I get `no_barcode`?

Check cropping, focus, glare, resolution, and the selected format filter.
Try leaving `formats` empty if the symbology is unknown.

#### Why did I get a download error?

Confirm that the file is publicly accessible without cookies or login and is within the size limit.
Private network and credential-bearing URLs are intentionally rejected.

#### Can it scan a PDF?

Not directly.
Convert PDF pages to PNG or JPEG images first, then provide the images or a ZIP archive.

#### Does it identify the product behind a UPC or EAN?

No.
It extracts the code value.
Use a product lookup service or the related UPC lookup Actor for enrichment.

### Related Actors by automation-lab

- [Barcode Generator](https://apify.com/automation-lab/barcode-generator) creates barcode PNG or SVG assets for labels and tests.
- [UPC Barcode Lookup](https://apify.com/automation-lab/upc-barcode-lookup) enriches a decoded UPC with product information when available.

Use Barcode Images to Excel first when your source is an image; add lookup only when product enrichment is required.

# Actor input Schema

## `imageUrls` (type: `array`):

HTTP(S) URLs of PNG, JPEG, WebP, GIF, BMP, or TIFF images to decode.

## `imageFile` (type: `string`):

Upload one barcode image or provide its key-value store/public URL.

## `zipFile` (type: `string`):

Upload a ZIP archive containing barcode images for a batch inventory import.

## `formats` (type: `array`):

Optional formats to scan. Leave empty to detect all supported 1D and 2D barcode formats.

## `maxImages` (type: `integer`):

Stop after this many URL, uploaded, and ZIP-entry images combined.

## `maxBarcodesPerImage` (type: `integer`):

Maximum barcode symbols returned from each image.

## `includeImagesWithoutBarcode` (type: `boolean`):

Add a traceability row when an image contains no detectable barcode.

## `requestTimeoutSecs` (type: `integer`):

Timeout for each public image or file download.

## Actor input object example

```json
{
  "imageUrls": [
    "https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=SKU-INV-0042"
  ],
  "maxImages": 100,
  "maxBarcodesPerImage": 20,
  "includeImagesWithoutBarcode": true,
  "requestTimeoutSecs": 30
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing decoded barcode rows, ready to download as Excel, CSV, or JSON.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "imageUrls": [
        "https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=SKU-INV-0042"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/barcode-images-to-excel").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "imageUrls": ["https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=SKU-INV-0042"] }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/barcode-images-to-excel").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "imageUrls": [
    "https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=SKU-INV-0042"
  ]
}' |
apify call automation-lab/barcode-images-to-excel --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/barcode-images-to-excel"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/I9Z7zXZHeRYFLmwyU/builds/GWKoCSYIx5fZ8MsTW/openapi.json
