> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alforse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 列印與標籤

> 將 ZPL 與 PDF 標籤傳送到實體印表機：設定印表機路由與各地點的指派，控制收貨、出貨、拆分與工單開工時的自動列印，並透過列印工作佇列追蹤每一張標籤。

列印功能會把實體標籤貼到零件、批次、貨架與看板料架上。管理員負責連接印表機並決定每個工作站使用哪一台；倉庫與現場人員則會在過帳收貨、拆分批次或完成工單的第一道工序時自動取得標籤。

## 概覽

列印系統由三個部分組成：

| 部分 | 角色 |
| - | - |
| **印表機路由** | 每台實體印表機一筆記錄，說明要送到哪裡，以及使用什麼格式。 |
| **指派** | 每個地點與情境由哪台印表機負責，以及是否自動列印。 |
| **列印工作佇列** | 每一次列印（無論自動或手動），從渲染到送達全程追蹤。 |

這與發票、採購單、報價單與工單流程卡等以檔案形式送達的產生文件不同。列印會將輸出送到**實體印表機**，且預設輸出為熱感應 ZPL 標籤。

### 格式

工作被路由到哪台印表機，決定它如何渲染：

* **ZPL** 是熱感應標籤印表機的指令語言，也是零件與儲位標籤的預設格式。ZPL 標籤只有在其紙張尺寸具有 ZPL 尺寸時才能渲染。
* **PDF** 是完整文件，由產生發票與流程卡的同一個 React-PDF 引擎繪製。看板卡**僅限 PDF**，因此除非有範本涵蓋，否則將看板卡傳送到僅支援 ZPL 的印表機會失敗。

### 文件類型

共定義三種標籤類型（`packages/web/printing/src/registry.ts` 中的 `documentTypeRegistry`）：

FieldType

<details>
  <summary>**productLabel**`zpl default`</summary>

  追蹤實體（序號或批次編號）的標籤。可從 `Receipt`、`Shipment`、`Operation`、`Entity`、`Job`、`Split` 或 `StockTransfer` 列印。
</details>

<details>
  <summary>**storageUnitLabel**`zpl default`</summary>

  貨架、料架或其他儲存位置的標籤。從 `StorageUnit` 列印。
</details>

<details>
  <summary>**kanbanCard**`pdf only`</summary>

  看板料架的補貨卡。從 `Kanban` 列印。
</details>

來源文件決定可以列印哪些類型：過帳出貨會產生產品標籤，掃描儲存單位則會產生儲位標籤。這項查詢由 `getDocumentTypesForSource` 執行。

## 設定列印

### 1. 新增印表機路由

**印表機路由**代表一台實體印表機。前往**設定 → 列印 → 印表機**，然後選取**新增印表機**。

FieldType

<details>
  <summary>**name**required`text`</summary>

  您為印表機取的名稱，例如「Zebra 2x1」。在同一地點內不可重複。
</details>

<details>
  <summary>**format**required`"zpl" | "pdf"`</summary>

  "ZPL (Thermal Label)" 或 "PDF (Document)"。
</details>

<details>
  <summary>**mediaSizeId**required`text`</summary>

  印表機中裝載的標籤尺寸。ZPL 印表機只提供熱感應（支援 ZPL）的尺寸；PDF 印表機則提供所有尺寸。
</details>

<details>
  <summary>**printerUrl**required`url`</summary>

  以 POST 接收渲染後標籤的 HTTP 端點。必須是有效的 URL。
</details>

<details>
  <summary>**apiKey**`text`</summary>

  選填。每次傳送時以 `X-API-Key` 標頭送出，並加密儲存。
</details>

<details>
  <summary>**templateId**`text`</summary>

  選填。"Leave blank for built-in"：留空表示使用 Alforse 內建的渲染器。
</details>

<details>
  <summary>**locationId**`text`</summary>

  選填。印表機所在的地點；未指定時，該路由適用於整個公司。
</details>

NOTE

Alforse 絕不會開啟印表機的原始連接埠。它透過 HTTP POST 將渲染後的位元組傳送到 `printerUrl`。因此現場印表機需要一個 Alforse 可以連到的 HTTP 端點，例如列印閘道或印表機自己的 HTTP 介面。目的地也必須是公司核准的印表機來源；Alforse 拒絕傳送到其他任何地方。

### 2. 測試印表機

每個路由都有**測試**（Test）動作，會將一張小型 ZPL 標籤直接傳送到其 `printerUrl`，讓您在依賴它之前確認印表機可以連線。測試僅適用於有紙張尺寸的 ZPL 路由，成功時會顯示 `"Test label sent to printer"`。

### 3. 將印表機指派給情境

路由是一台印表機；**指派**則決定何時使用它。開啟**設定 → 列印 → 指派**，每個地點都有自己的區塊。在其中為每個**情境**指定一台印表機（`packages/web/printing/src/assignments.ts` 中的 `printerContexts`）：

FieldType

<details>
  <summary>**default**</summary>

  地點的備援。任何沒有自己印表機的情境都使用這一台。
</details>

<details>
  <summary>**shipping**</summary>

  用於類型為 `Shipment` 的來源文件。
</details>

<details>
  <summary>**receiving**</summary>

  用於類型為 `Receipt` 的來源文件。
</details>

<details>
  <summary>**inventory**</summary>

  用於 `StockTransfer` 或 `StorageUnit`。
</details>

<details>
  <summary>**workCenter**</summary>

  依工作中心設定，用於從工單工序列印的標籤。沒有指派的工作中心會直接使用地點的預設值。
</details>

每個情境列也有**自動列印**（Auto-print）開關；開啟時，對應的業務事件會在無人點選的情況下自動列印。`getPrinterContextForSource` 會找出來源文件的情境，`resolveContextAssignment` 則套用備援，因此未指派的情境會使用地點的預設印表機。

HEADS UP

沒有明確列的情境，其自動列印為**開啟**，即使地點的預設列已將其關閉。若要讓某個工作站保持安靜（例如出貨），請為它建立自己的列並關閉自動列印，而不要依賴預設列。

## 自動列印

在支援的業務事件之後，Alforse 會找出該地點與情境的印表機，檢查 `autoPrint`（未設定時視為**開啟**），並將工作排入佇列。列印失敗絕不會阻擋觸發它的收貨、出貨或工單。

| 事件 | 情境 | 列印內容 |
| - | - | - |
| 收貨已過帳 | receiving | 所收追蹤實體的產品標籤。 |
| 出貨已過帳 | shipping | 產品標籤，加上批次拆分的 `Split` 標籤。 |
| 調撥明細被拆分 | inventory | 一張 `Split` 標籤，以及原始批次的 `Entity` 重新列印。 |
| 在 MES 中完成工單的第一道工序 | work center | 該工單的產品標籤。 |

若要讓某個工作站安靜，請在該地點該情境的列上關閉**自動列印**。

HEADS UP

同一來源文件的自動列印會在 **30 秒內去重**：第二個事件會被捨棄，並產生不可重試的錯誤。手動列印與重新列印絕不會去重。

## 手動列印

在相關畫面上選取**列印**，或將來源文件傳送到手動列印路由（`/x/print`），該路由會驗證請求並排入相同類型的工作。

**列印**的行為取決於地點：

| 地點有印表機路由 | 行為 |
| - | - |
| 有 | 開啟印表機選擇器，並選取解析出的預設印表機。確認後將工作排入佇列。 |
| 沒有 | 開啟**下載**視窗，讓您將標籤儲存為 ZPL 或 PDF。 |

## 列印工作佇列

### 工作狀態

<details>
  <summary>**generating**</summary>

  工作已存在，其內容正在渲染，形式為 ZPL 文字或 base64 PDF。
</details>

<details>
  <summary>**queued**</summary>

  已渲染。傳送到印表機的作業已排入佇列。
</details>

<details>
  <summary>**printing**</summary>

  已送到印表機端點；傳送進行中。
</details>

<details open>
  <summary>**completed**</summary>

  已送達，或在沒有印表機可傳送的情況下完成渲染（僅供下載的工作）。
</details>

<details>
  <summary>**failed**</summary>

  渲染或傳送失敗，或無法確認傳送。`error` 說明原因，`attempts` 記錄嘗試次數。
</details>

每個工作都會記錄其 `origin`：

| 來源 | 意義 |
| - | - |
| **auto** | 業務事件之後自動列印。 |
| **manual** | 有人選取了列印。 |
| **reprint** | 從工作清單重新執行。 |

工作還會儲存 `sourceDocument`、`sourceDocumentId`、可讀的 ID、`contentType`，以及送往的 `printerUrl`。

### 監控與重新列印

開啟**設定 → 列印 → 列印工作**。表格會即時更新，顯示狀態、說明、來源、類型、來源（origin）與時間。展開某一列可查看印表機 URL、嘗試次數、時間戳記與任何錯誤。您可以在列上：

* **檢視**內容：ZPL 透過 Labelary 預覽，PDF 則在內嵌框架中顯示；
* **重新列印**，這會建立 `origin: "reprint"` 的新工作；
* **刪除**它。

NOTE

如果傳送結果無法確認，因為逾時或結果無法記錄，工作會被標記為失敗，且**絕不會自動重送**：標籤可能已經印出。請檢查印表機，必要時再**重新列印**。

## 標籤尺寸

紙張尺寸來自固定的目錄（`packages/web/utils/src/labels.ts`）：`label2x1`、`label4x2`、公制的 `label100x50mm` 與 `label50x25mm`，以及僅限 PDF 的 `avery5163`。只有具備 ZPL 尺寸的規格才能在熱感應印表機上列印，因此 Avery 這類僅限 PDF 的尺寸無法列印。

尺寸在兩個地方設定：

* 每個印表機路由固定自己的 `mediaSizeId`，與該印表機中裝載的標籤相符；
* 公司的**預設產品標籤尺寸**（`companySettings.productLabelSize`）在文件範本畫面設定，當沒有路由設定尺寸時，互動式標籤下載路由會使用它。

請參閱[公司設定](https://docs.alforse.com/zh-Hant/docs/reference/company-settings.md)了解該預設值的位置，並參閱[文件](https://docs.alforse.com/zh-Hant/docs/reference/documents.md)了解為內建標籤範本設定樣式的自訂工具。

## 疑難排解

### 標籤沒有印出

請依序檢查：

1. 該地點與情境已指派印表機路由，且其**自動列印**開關為開啟。
2. 路由有可連線的 `printerUrl`。沒有的話，工作會渲染但無法傳送。
3. 該工作在**設定 → 列印 → 列印工作**中沒有處於**失敗**狀態。展開該列以閱讀 `error`。

排入自動列印佇列時的失敗會記錄為 "Auto-print failed"，且絕不會顯示在收貨或出貨畫面上，因此請到列印工作清單查看。若完全沒有工作，原因是沒有解析出印表機而且自動列印已關閉，或該事件不屬於會自動列印的事件。只有[自動列印](#automatic-printing)中的四種事件會自動列印；其他情況請使用**列印**或手動路由。

### 錯誤訊息

| 訊息 | 原因 | 解決方式 |
| - | - | - |
| "Print jobs already exist for … …" | 同一來源文件的自動工作在 30 秒內已建立，因此捨棄了這個重複項。 | 需要另一份副本時使用**重新列印**；重新列印不會去重。 |
| "Rendering failed: …" | 無法產生內容，常見原因是 ZPL 標籤被路由到沒有 ZPL 尺寸的紙張尺寸，或僅限 PDF 的看板卡被送到僅支援 ZPL 的印表機。 | 檢查路由的紙張尺寸與格式。 |
| "Printer delivery could not be confirmed. This job will not be sent again automatically." | 端點未及時回應，或結果無法記錄。 | 檢查印表機；若沒有印出任何內容，請從工作清單重新列印。 |
| "Print job not found: …" / "The print job has no valid stored content." | 傳送時無法載入工作或其內容；後者表示渲染從未完成。 | 在工作清單中檢查該工作的狀態與錯誤。 |
| "No printer is assigned to this print job; nothing was sent." | 對沒有印表機的工作要求重新列印。 | 為該地點與情境指派印表機，然後再次列印。 |
| "Print failed (…)" | 端點回傳 HTTP 錯誤，代碼在訊息中。通常是印表機離線、`printerUrl` 錯誤，或 `apiKey` 遺失或無效。 | 使用路由的**測試**動作檢查連線能力。 |
| "Test print is only supported for ZPL label printers with a media size configured." | 對 PDF 路由或沒有紙張尺寸的 ZPL 路由使用了**測試**。 | 只測試有紙張尺寸的 ZPL 路由。 |
| "Cannot reprint a job with no content" / "Cannot reprint a job that is still generating" | 重新列印會複製原工作渲染後的內容，而這個工作從未渲染。 | 先解決原始工作，或從來源文件再次列印。 |

## 相關內容

**公司設定**

預設產品標籤尺寸，以及其他公司層級的列印預設值。

[Open](https://docs.alforse.com/zh-Hant/docs/reference/company-settings.md)

**庫存與地點**

儲位標籤，以及多數列印工作所描述的追蹤實體。

[Open](https://docs.alforse.com/zh-Hant/docs/reference/inventory.md)

**追溯性**

產品標籤所載的序號與批次編號。

[Open](https://docs.alforse.com/zh-Hant/docs/reference/traceability.md)

**看板**

補貨料架，以及為它們列印的 PDF 卡片。

[Open](https://docs.alforse.com/zh-Hant/docs/reference/kanban.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.