|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- # Excel export standard (FPSMS frontend)
-
- This document defines how **client-side** `.xlsx` exports should look and behave. **Implementation:** `exportChartToXlsx.ts` and `exportMultiSheetToXlsx()` — use these helpers for new reports so styling stays consistent.
-
- ## Scope (important)
-
- | Export path | Follows this `.md`? |
- |-------------|---------------------|
- | **Next.js** builds the file via `exportChartToXlsx` / `exportMultiSheetToXlsx` (e.g. **PO 入倉記錄** / `rep-014`) | **Yes** — rules are enforced in code. |
- | **Backend** returns ready-made `.xlsx` or Excel bytes (JasperReports, Apache POI, etc.; most `print-*` report endpoints) | **No — not automatically.** That code does **not** use this TypeScript module. To match the same **look** (grey headers, number formats, alignment), implement equivalent styling in Java/Kotlin or Jasper templates. See the backend companion doc below. |
-
- **Backend companion (visual parity):**
- `FPSMS-backend/docs/EXCEL_EXPORT_STANDARD.md` — same *rules*, for POI/Jasper implementers.
-
- ---
-
- ## 1. Library
-
- | Item | Value |
- |------|--------|
- | Package | **`xlsx-js-style`** (not the plain `xlsx` community build) |
- | Reason | Plain SheetJS **does not persist** cell styles (`fill`, `alignment`, `numFmt`) in the written file. `xlsx-js-style` is a compatible fork that **does**. |
-
- ---
-
- ## 2. Data shape
-
- - Rows are **`Record<string, unknown>[]`** (array of plain objects).
- - **First object’s keys** become the **header row** (column titles). Every row should use the **same keys** in the same order for a rectangular sheet.
- - Prefer **real JavaScript `number`** values for amounts where possible; the exporter will apply number formats. Strings that look like numbers (e.g. `"1,234.56"`) are parsed for money columns.
-
- ---
-
- ## 3. Processing order (per sheet)
-
- After `json_to_sheet(rows)`:
-
- 1. **`!cols`** — column width heuristic (see §4).
- 2. **`applyHeaderRowStyle`** — header row styling (see §5).
- 3. **`applyMoneyColumnNumberFormats`** — money columns only, data rows (see §6).
- 4. **`applyNumericColumnRightAlign`** — money + quantity columns, **all rows including header** (see §7).
-
- ---
-
- ## 4. Column width (`!cols`)
-
- - For each column: `wch = max(12, headerText.length + 4)`.
- - Adjust if a report needs fixed widths; default keeps bilingual headers readable.
-
- ---
-
- ## 5. Header row style (row 0)
-
- Applied to **every** header cell first; numeric columns get alignment overridden in step 4.
-
- | Property | Value |
- |----------|--------|
- | Font | Bold, black `rgb: "000000"` |
- | Fill | Solid, `fgColor: "D9D9D9"` (light grey) |
- | Alignment (default) | Horizontal **center**, vertical **center**, `wrapText: true` |
-
- ---
-
- ## 6. Money / amount columns — number format
-
- **Detection:** header label matches (case-insensitive):
-
- ```text
- 金額 | 單價 | Amount | Unit Price | Total Amount
- ```
-
- (Also matches bilingual headers that contain these fragments, e.g. `Amount / 金額`, `Unit Price / 單價`, `Total Amount / 金額`.)
-
- **Rules:**
-
- - Applies to **data rows only** (not row 0).
- - Excel format string: **`#,##0.00`** (thousands separator + 2 decimals). Stored on the cell as `z`.
- - Cell type `t: "n"` for numeric values.
- - If the cell is a **string**, commas are stripped and the value is parsed to a number when possible.
-
- **Naming new reports:** use header text that matches the patterns above so columns pick up formatting automatically.
-
- ---
-
- ## 7. Quantity columns — alignment only
-
- **Detection:** header label matches:
-
- ```text
- Qty | 數量 | Demand
- ```
-
- (Covers e.g. `Qty / 數量`, `Demand Qty / 訂單數量`.)
-
- - No default thousands format (quantities may have up to 4 decimals in app code).
- - These columns are **right-aligned** together with money columns (see §8).
-
- ---
-
- ## 8. Alignment — numeric columns (header + data)
-
- **Detection:** union of **money** (§6) and **quantity** (§7) header patterns.
-
- | Alignment | Value |
- |-----------|--------|
- | Horizontal | **`right`** |
- | Vertical | **`center`** |
- | `wrapText` | Preserved / defaulted to `true` where applicable |
-
- Existing style objects are **merged** (fill, font from header styling are kept).
-
- ---
-
- ## 9. Multi-sheet workbook
-
- | Rule | Detail |
- |------|--------|
- | API | `exportMultiSheetToXlsx({ name, rows }[], filename)` |
- | Sheet name length | Truncated to **31** characters (Excel limit) |
- | Each sheet | Same pipeline as §3 if `rows.length > 0` |
-
- ---
-
- ## 10. Empty sheets
-
- If `rows.length === 0`, a minimal sheet is written; no header styling pipeline runs.
-
- ---
-
- ## 11. Reports using this standard today
-
- | Feature | Location |
- |---------|----------|
- | Chart export | Uses `exportChartToXlsx` |
- | GRN / PO 入倉記錄 (`rep-014`) | `src/app/(main)/report/grnReportApi.ts` — builds row objects, calls `exportChartToXlsx` / `exportMultiSheetToXlsx` |
-
- Most other reports on `/report` download Excel/PDF **generated on the server** (Jasper, etc.). Those **do not** run this TypeScript pipeline; use **`FPSMS-backend/docs/EXCEL_EXPORT_STANDARD.md`** if you want the same visual rules there.
-
- ---
-
- ## 12. Checklist for new Excel exports
-
- 1. Import from **`xlsx-js-style`** only if building sheets manually; otherwise call **`exportChartToXlsx`** or **`exportMultiSheetToXlsx`**.
- 2. Use **stable header strings** that match §6 / §7 if the column is amount or quantity.
- 3. Pass **numbers** for amounts when possible.
- 4. If you need a **new** category (e.g. “Rate”, “折扣”), extend the regex constants in `exportChartToXlsx.ts` and **update this document**.
- 5. Keep filenames and sheet names user-readable; remember the **31-character** sheet limit.
-
- ---
-
- ## 13. Related files
-
- | File | Role |
- |------|------|
- | `exportChartToXlsx.ts` | Single-sheet export + styling pipeline |
- | `grnReportApi.ts` | Example: bilingual headers, money values, multi-sheet GRN report |
- | `FPSMS-backend/docs/EXCEL_EXPORT_STANDARD.md` | Backend Excel (POI/Jasper) — same *rules*, separate code |
-
- ---
-
- *Last aligned with implementation in `exportChartToXlsx.ts` (header fill `#D9D9D9`, money format `#,##0.00`, right-align numeric columns).*
|