@agile-team/mach-report 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +130 -16
  2. package/dist/ReportPreview-CLENbOCL.cjs +6 -0
  3. package/dist/ReportPreview-CwTGfyTq.js +1679 -0
  4. package/dist/grid-geometry-CWmJ9c9y.js +130 -0
  5. package/dist/grid-geometry-DBH9ExuY.cjs +1 -0
  6. package/dist/index.cjs +5 -5
  7. package/dist/index.d.cts +110 -16
  8. package/dist/index.d.ts +110 -16
  9. package/dist/index.js +1099 -718
  10. package/dist/page-window-index-CIuT4BAv.js +43 -0
  11. package/dist/page-window-index-DEjnM6IB.cjs +1 -0
  12. package/dist/pdf.cjs +46 -46
  13. package/dist/pdf.d.cts +20 -0
  14. package/dist/pdf.d.ts +20 -0
  15. package/dist/pdf.js +6 -6
  16. package/dist/{plugin-Bl00j_CP.cjs → plugin-MSh_OhoW.cjs} +1 -1
  17. package/dist/{plugin-DVScnZ4C.js → plugin-uoO9VA6O.js} +2 -2
  18. package/dist/report-params-B3Fia6JO.js +10 -0
  19. package/dist/report-params-D1gZ1DME.cjs +1 -0
  20. package/dist/style.css +1 -1
  21. package/dist/textwrap-BQyrpYSR.js +117 -0
  22. package/dist/textwrap-DqiFwAV3.cjs +3 -0
  23. package/dist/vue/async.d.cts +77 -2
  24. package/dist/vue/async.d.ts +77 -2
  25. package/dist/vue/index.d.cts +91 -14
  26. package/dist/vue/index.d.ts +91 -14
  27. package/dist/vue-async.cjs +1 -1
  28. package/dist/vue-async.js +3 -3
  29. package/dist/vue.cjs +1 -1
  30. package/dist/vue.js +4 -4
  31. package/dist/xlsx.cjs +21 -21
  32. package/dist/xlsx.d.cts +28 -2
  33. package/dist/xlsx.d.ts +28 -2
  34. package/dist/xlsx.js +5637 -5515
  35. package/package.json +3 -2
  36. package/dist/ReportPreview-Dwdsyk9b.js +0 -1558
  37. package/dist/ReportPreview-VHAIfsz1.cjs +0 -6
  38. package/dist/grid-geometry-BXpOxznT.cjs +0 -1
  39. package/dist/grid-geometry-Bs8QXz1X.js +0 -65
  40. package/dist/report-params-BB85g7mg.js +0 -10
  41. package/dist/report-params-D1NeY-eR.cjs +0 -1
  42. package/dist/style-CFZ-HE2s.cjs +0 -3
  43. package/dist/style-DnmtG7Gl.js +0 -180
package/dist/index.d.cts CHANGED
@@ -102,14 +102,7 @@ export declare interface ComponentStyle {
102
102
  rotateDeg?: number;
103
103
  }
104
104
 
105
- /**
106
- * 页级视口虚拟化:给定每页高度与滚动位置,返回需要真实渲染的页区间
107
- * 与上下占位高度。start/end 为闭区间索引。
108
- *
109
- * 布局模型:每页占据 height + gap(gap 为页间距,默认 0),
110
- * padTop/padBottom 同口径累计,保证 占位+渲染页+间距 还原总滚动高度。
111
- * 内部用前缀和 + 二分定位覆盖页与可见终点。
112
- */
105
+ /** 页级视口虚拟化;单次计算入口保留兼容,预览内部复用已建立的几何索引。 */
113
106
  export declare function computePageWindow(input: PageWindowInput): PageWindow;
114
107
 
115
108
  /**
@@ -140,13 +133,16 @@ export declare function createReportSource(reports: ReportRegistry, options?: {
140
133
  }): ReportSource;
141
134
 
142
135
  /**
143
- * 创建一页标准明细模板;分页与格式化继续由 paginateTemplate 处理。
144
- * 固定列保持毫米宽度,自动列共享余量;全部固定列时表格宽度为列宽之和。
136
+ * 创建明细模板;分页与格式化继续由 paginateTemplate 处理。
137
+ * page 模式自动列共享纸张余量;wide 模式按自然列宽扩展,不缩小字号或压缩列。
145
138
  */
146
139
  export declare function createTableTemplate(options: TableTemplateOptions): ReportTemplate;
147
140
 
148
141
  export declare function createTemplate(): TemplateBuilder;
149
142
 
143
+ /** 存储无关的模板目录;后台 CRUD、权限、发布审批与持久化由宿主接入。 */
144
+ export declare function createTemplateRegistry(documents?: readonly ReportTemplateDocument[]): ReportTemplateRegistry;
145
+
150
146
  export declare const CSS_DPI = 96;
151
147
 
152
148
  export declare type DatasetRows = Record<string, Record<string, unknown>[]>;
@@ -168,6 +164,11 @@ export declare function defineReport<TData>(definition: ReportDefinitionOptions<
168
164
 
169
165
  export declare function defineReport(definition: ReportDefinition): ReportDefinition;
170
166
 
167
+ /** 创建带文档版本的模板快照,使用侧无需记忆 schemaVersion 常量。 */
168
+ export declare function defineReportTemplate(document: Omit<ReportTemplateDocument, "schemaVersion"> & {
169
+ schemaVersion?: typeof REPORT_TEMPLATE_DOCUMENT_VERSION;
170
+ }): ReportTemplateDocument;
171
+
171
172
  /**
172
173
  * 规则求值语义:
173
174
  * - 空值(null/undefined/"")永不命中(避免 Number("")===0 把空当 0 的隐式陷阱)
@@ -188,6 +189,10 @@ declare type Geometry = Partial<Pick<PlanComponent, "leftMm" | "topMm" | "widthM
188
189
  export declare interface GridCell {
189
190
  text?: string;
190
191
  rawText?: string;
192
+ /** 原始值,仅供 Excel raw 模式消费;不参与预览、分页与 PDF 绘制。 */
193
+ value?: string | number | boolean | null;
194
+ /** Excel 数字格式(例如 #,##0.00 / 0.00%),不改变 text。 */
195
+ numberFormat?: string;
191
196
  children?: PlanComponent[];
192
197
  colSpan?: number;
193
198
  rowSpan?: number;
@@ -248,11 +253,20 @@ export declare function isRichText(comp: PlanComponent): boolean;
248
253
  /** 默认行高倍数(基线距 = 字号 × 该系数) */
249
254
  export declare const LINE_HEIGHT = 1.35;
250
255
 
256
+ /** auto:真实数字/显式数值格式居右,日期与布尔居中,其他内容居左。 */
257
+ export declare type ListAlignment = NonNullable<ComponentStyle["align"]> | "auto";
258
+
251
259
  export declare interface ListColumn {
252
260
  header: string;
253
261
  field: string;
254
262
  widthMm: number;
255
263
  style?: ComponentStyle;
264
+ /** 内容对齐,优先于 style.align;数值字符串不会自动判为数字。 */
265
+ align?: ListAlignment;
266
+ /** 独立的表头对齐,不改变内容对齐。 */
267
+ headerAlign?: ComponentStyle["align"];
268
+ /** 独立的表头样式,优先于列表级表头样式。 */
269
+ headerStyle?: ComponentStyle;
256
270
  /** 值格式化(声明式):千分位/小数位、百分比、日期 pattern */
257
271
  format?: ColumnFormat;
258
272
  /** 条件格式规则(声明式,命中合并进单元格样式;如负数红字) */
@@ -262,6 +276,10 @@ export declare interface ListColumn {
262
276
  export declare interface ListComponent {
263
277
  kind: "list";
264
278
  id?: string;
279
+ /** 宽表标记用于连续 Excel;不改变低层列表的列宽和分页算法。 */
280
+ layout?: "page" | "wide";
281
+ /** 逻辑表名称,供 Excel Sheet 命名;不额外生成标题组件。 */
282
+ title?: string;
265
283
  leftMm: number;
266
284
  topMm: number;
267
285
  widthMm: number;
@@ -273,6 +291,11 @@ export declare interface ListComponent {
273
291
  paddingMm?: number;
274
292
  headerEveryPage?: boolean;
275
293
  headerBackgroundColor?: string;
294
+ /** 内容默认对齐,列配置可覆盖;低层模板缺省仍为 left。 */
295
+ align?: ListAlignment;
296
+ /** 表头默认对齐,列配置可覆盖。 */
297
+ headerAlign?: ComponentStyle["align"];
298
+ headerStyle?: ComponentStyle;
276
299
  border?: boolean;
277
300
  /** 分组小计(组头/组尾小计/组头防孤行) */
278
301
  groupBy?: ListGroupBy;
@@ -351,7 +374,7 @@ export declare interface PageWindowInput {
351
374
  viewportHeightPx: number;
352
375
  scrollTopPx: number;
353
376
  overscan?: number;
354
- /** 页间距(px)。占位高度按“每页高度+间距”累计,与 margin-bottom 布局一致;默认 0 */
377
+ /** 页间距(px),默认 0;与每页 margin-bottom 使用同一口径。 */
355
378
  gapPx?: number;
356
379
  }
357
380
 
@@ -380,6 +403,9 @@ export declare type PaperName = keyof typeof PAPER_SIZES;
380
403
  /** 日历日字符串 → 本地 Date(不含时间的纯日期,杜绝 UTC 偏移) */
381
404
  export declare function parseDateLocal(input: string): Date | null;
382
405
 
406
+ /** 校验文件 JSON 文本或接口返回的未知对象,返回独立模板快照。 */
407
+ export declare function parseReportTemplate(input: unknown): ReportTemplateDocument;
408
+
383
409
  export declare interface PlanComponent {
384
410
  kind: ComponentKind;
385
411
  leftMm: number;
@@ -394,6 +420,7 @@ export declare interface PlanComponent {
394
420
  richParagraphs?: RichParagraph[];
395
421
  imageData?: string;
396
422
  grid?: PlanGrid;
423
+ table?: PlanTableFragment;
397
424
  style?: ComponentStyle;
398
425
  meta?: Record<string, unknown>;
399
426
  /** MachReport 扩展字段:未知 kind 的兜底渲染标记 */
@@ -415,6 +442,8 @@ export declare interface PlanGrid {
415
442
  }
416
443
 
417
444
  export declare interface PlanPage {
445
+ /** wide 表示完整自然列宽;页面仅为预览的垂直窗口分段。 */
446
+ layout?: "page" | "wide";
418
447
  pageWidthMm: number;
419
448
  pageHeightMm: number;
420
449
  marginTopMm?: number;
@@ -424,6 +453,19 @@ export declare interface PlanPage {
424
453
  components: PlanComponent[];
425
454
  }
426
455
 
456
+ /** 列表的逻辑行来源;用于连续 Excel 重组,避免按文本猜测重复表头。 */
457
+ export declare interface PlanTableFragment {
458
+ /** 在整个计划中唯一的逻辑表身份;同一表的分页片段共享身份。 */
459
+ id: string;
460
+ /** 表头固定 -1;其余行(包括组头/小计/总计)从 0 连续递增。 */
461
+ rowIndex: number;
462
+ role: "header" | "body" | "group-header" | "subtotal" | "grand-total";
463
+ /** 按物理列顺序保存字段身份;不以表头显示文本判断列结构。 */
464
+ columnKeys: string[];
465
+ layout?: "page" | "wide";
466
+ title?: string;
467
+ }
468
+
427
469
  export declare function ptToPx(pt: number, dpi?: number): number;
428
470
 
429
471
  export declare function pxToMm(value: number, dpi?: number): number;
@@ -462,12 +504,16 @@ export declare function renderPlanToCanvas(plan: RenderPlan, options?: CanvasRen
462
504
  */
463
505
  export declare function renderPlanToImages(plan: RenderPlan, options?: ImageRenderOptions): Promise<ImageRenderResult>;
464
506
 
507
+ /** 模板存储文档版本;与渲染计划版本独立演进。 */
508
+ export declare const REPORT_TEMPLATE_DOCUMENT_VERSION: "1.0";
509
+
465
510
  export declare interface ReportDefinition {
466
- template: ReportTemplate;
511
+ /** 静态模板或宿主提供的异步模板加载器;动态模板默认每次重新读取,不缓存版本。 */
512
+ template: ReportTemplate | ReportTemplateLoader;
467
513
  /** 静态数据;load 存在时优先使用 load 的结果。 */
468
514
  datasets?: DatasetRows;
469
515
  load?: (context: ReportLoadContext) => DatasetRows | Promise<DatasetRows>;
470
- /** 覆盖模板参数定义,未提供时自动使用 template.params。 */
516
+ /** 覆盖模板参数定义;动态模板应在此声明查询面板元数据,避免查询前先请求模板。 */
471
517
  params?: ReportParamDef[];
472
518
  pagination?: PaginateOptions;
473
519
  }
@@ -534,6 +580,37 @@ export declare interface ReportTemplate {
534
580
  pages: TemplatePage[];
535
581
  }
536
582
 
583
+ /** 可存入数据库/文件的纯 JSON 模板;数据、接口与鉴权仍由宿主提供。 */
584
+ export declare interface ReportTemplateDocument {
585
+ schemaVersion: typeof REPORT_TEMPLATE_DOCUMENT_VERSION;
586
+ id: string;
587
+ name: string;
588
+ /** 宿主的发布版本/乐观锁标识,不由引擎自动递增。 */
589
+ revision?: string;
590
+ description?: string;
591
+ template: ReportTemplate;
592
+ }
593
+
594
+ export declare class ReportTemplateError extends Error {
595
+ readonly errors: readonly ValidationError[];
596
+ constructor(errors: readonly ValidationError[]);
597
+ }
598
+
599
+ export declare type ReportTemplateLoader = (context: ReportLoadContext) => ReportTemplate | Promise<ReportTemplate>;
600
+
601
+ export declare interface ReportTemplateRegistry {
602
+ /** 返回独立快照,调用方编辑不会改变目录中的已注册模板。 */
603
+ get(id: string): ReportTemplateDocument | undefined;
604
+ list(): ReportTemplateSummary[];
605
+ /** 重复 ID 默认拒绝;更新必须显式 replace:true。 */
606
+ register(document: ReportTemplateDocument, options?: {
607
+ replace?: boolean;
608
+ }): void;
609
+ remove(id: string): boolean;
610
+ }
611
+
612
+ export declare type ReportTemplateSummary = Omit<ReportTemplateDocument, "template">;
613
+
537
614
  /**
538
615
  * 边框开关解析:
539
616
  * - 未声明(undefined)→ 四边全开(与既有 rect 总有边框的行为兼容)
@@ -604,6 +681,9 @@ export declare function round(value: number, digits: number): number;
604
681
  /** RenderPlan 正式 schema 版本(core 分页引擎产出) */
605
682
  export declare const SCHEMA_VERSION_MACH = "1.0.0-mach";
606
683
 
684
+ /** 格式化输出已校验的纯模板 JSON,不静默丢弃函数或非法数字。 */
685
+ export declare function serializeReportTemplate(document: ReportTemplateDocument): string;
686
+
607
687
  /** 条件格式规则求值(声明式,见 ListColumn.rules) */
608
688
  export declare interface StyleRule {
609
689
  when: {
@@ -615,16 +695,20 @@ export declare interface StyleRule {
615
695
  style: Record<string, unknown>;
616
696
  }
617
697
 
618
- /** 标准明细列:显式 widthMm 优先;其余列按 flex 分配剩余可用宽度。 */
698
+ /** 明细列:显式 widthMm 优先;纸张模式按 flex 分余量,宽表模式按 flex 放大基准列宽。 */
619
699
  export declare type TableTemplateColumn = Omit<ListColumn, "widthMm"> & {
620
700
  widthMm?: number;
621
701
  /** 自动列的宽度权重,默认 1(有 widthMm 时不参与分配)。 */
622
702
  flex?: number;
623
703
  };
624
704
 
625
- export declare type TableTemplateListOptions = Partial<Omit<ListComponent, "kind" | "leftMm" | "topMm" | "widthMm" | "dataset" | "columns">>;
705
+ export declare type TableTemplateListOptions = Partial<Omit<ListComponent, "kind" | "leftMm" | "topMm" | "widthMm" | "dataset" | "columns" | "layout" | "title">>;
626
706
 
627
707
  export declare interface TableTemplateOptions extends PageOptions {
708
+ /** page 保持旧版纸张布局;wide 按所有列的自然宽度扩展,纵向分段仅供预览与渲染。 */
709
+ layout?: "page" | "wide";
710
+ /** 宽表模式自动列的基准宽度,默认 30mm;widthMm 优先,flex 为基准宽度的倍数。 */
711
+ columnWidthMm?: number;
628
712
  title?: string;
629
713
  /** 标题占高,默认 10mm;没有标题时不占空间。 */
630
714
  titleHeightMm?: number;
@@ -633,7 +717,7 @@ export declare interface TableTemplateOptions extends PageOptions {
633
717
  titleStyle?: ComponentStyle;
634
718
  dataset?: string;
635
719
  columns: readonly TableTemplateColumn[];
636
- /** 默认 A4;页边距各默认 10mm。 */
720
+ /** 纸张模式默认 A4;与 layout: "wide" 互斥;页边距各默认 10mm。 */
637
721
  paper?: PaperName | {
638
722
  widthMm: number;
639
723
  heightMm: number;
@@ -681,6 +765,8 @@ export declare type TemplateComponent = PlanComponent | ListComponent;
681
765
  export declare interface TemplatePage {
682
766
  widthMm: number;
683
767
  heightMm: number;
768
+ /** 宽表保持全列自然宽度,页高只控制内部纵向分段。 */
769
+ layout?: "page" | "wide";
684
770
  marginTopMm?: number;
685
771
  marginBottomMm?: number;
686
772
  marginLeftMm?: number;
@@ -706,6 +792,9 @@ export declare interface TextMeasurer {
706
792
  measureMm(text: string, options: TextMeasureOptions): number;
707
793
  }
708
794
 
795
+ /** 数值型 Excel 导出的显示格式;日期/对象仍使用显示文本,不做隐式类型转换。 */
796
+ export declare function toExcelNumberFormat(format?: ColumnFormat): string | undefined;
797
+
709
798
  export declare function toNumber(value: unknown): number | null;
710
799
 
711
800
  export declare function validateComponent(comp: unknown, path: string, errors: ValidationError[], warnings?: ValidationError[]): void;
@@ -714,6 +803,11 @@ export declare function validatePage(page: unknown, path: string, errors: Valida
714
803
 
715
804
  export declare function validateRenderPlan(input: unknown): ValidationResult;
716
805
 
806
+ /** 对入库/导入模板做声明式校验,不执行分页或数据请求。 */
807
+ export declare function validateReportTemplate(input: unknown): ValidationResult;
808
+
809
+ export declare function validateReportTemplateDocument(input: unknown): ValidationResult;
810
+
717
811
  export declare interface ValidationError {
718
812
  path: string;
719
813
  message: string;
package/dist/index.d.ts CHANGED
@@ -102,14 +102,7 @@ export declare interface ComponentStyle {
102
102
  rotateDeg?: number;
103
103
  }
104
104
 
105
- /**
106
- * 页级视口虚拟化:给定每页高度与滚动位置,返回需要真实渲染的页区间
107
- * 与上下占位高度。start/end 为闭区间索引。
108
- *
109
- * 布局模型:每页占据 height + gap(gap 为页间距,默认 0),
110
- * padTop/padBottom 同口径累计,保证 占位+渲染页+间距 还原总滚动高度。
111
- * 内部用前缀和 + 二分定位覆盖页与可见终点。
112
- */
105
+ /** 页级视口虚拟化;单次计算入口保留兼容,预览内部复用已建立的几何索引。 */
113
106
  export declare function computePageWindow(input: PageWindowInput): PageWindow;
114
107
 
115
108
  /**
@@ -140,13 +133,16 @@ export declare function createReportSource(reports: ReportRegistry, options?: {
140
133
  }): ReportSource;
141
134
 
142
135
  /**
143
- * 创建一页标准明细模板;分页与格式化继续由 paginateTemplate 处理。
144
- * 固定列保持毫米宽度,自动列共享余量;全部固定列时表格宽度为列宽之和。
136
+ * 创建明细模板;分页与格式化继续由 paginateTemplate 处理。
137
+ * page 模式自动列共享纸张余量;wide 模式按自然列宽扩展,不缩小字号或压缩列。
145
138
  */
146
139
  export declare function createTableTemplate(options: TableTemplateOptions): ReportTemplate;
147
140
 
148
141
  export declare function createTemplate(): TemplateBuilder;
149
142
 
143
+ /** 存储无关的模板目录;后台 CRUD、权限、发布审批与持久化由宿主接入。 */
144
+ export declare function createTemplateRegistry(documents?: readonly ReportTemplateDocument[]): ReportTemplateRegistry;
145
+
150
146
  export declare const CSS_DPI = 96;
151
147
 
152
148
  export declare type DatasetRows = Record<string, Record<string, unknown>[]>;
@@ -168,6 +164,11 @@ export declare function defineReport<TData>(definition: ReportDefinitionOptions<
168
164
 
169
165
  export declare function defineReport(definition: ReportDefinition): ReportDefinition;
170
166
 
167
+ /** 创建带文档版本的模板快照,使用侧无需记忆 schemaVersion 常量。 */
168
+ export declare function defineReportTemplate(document: Omit<ReportTemplateDocument, "schemaVersion"> & {
169
+ schemaVersion?: typeof REPORT_TEMPLATE_DOCUMENT_VERSION;
170
+ }): ReportTemplateDocument;
171
+
171
172
  /**
172
173
  * 规则求值语义:
173
174
  * - 空值(null/undefined/"")永不命中(避免 Number("")===0 把空当 0 的隐式陷阱)
@@ -188,6 +189,10 @@ declare type Geometry = Partial<Pick<PlanComponent, "leftMm" | "topMm" | "widthM
188
189
  export declare interface GridCell {
189
190
  text?: string;
190
191
  rawText?: string;
192
+ /** 原始值,仅供 Excel raw 模式消费;不参与预览、分页与 PDF 绘制。 */
193
+ value?: string | number | boolean | null;
194
+ /** Excel 数字格式(例如 #,##0.00 / 0.00%),不改变 text。 */
195
+ numberFormat?: string;
191
196
  children?: PlanComponent[];
192
197
  colSpan?: number;
193
198
  rowSpan?: number;
@@ -248,11 +253,20 @@ export declare function isRichText(comp: PlanComponent): boolean;
248
253
  /** 默认行高倍数(基线距 = 字号 × 该系数) */
249
254
  export declare const LINE_HEIGHT = 1.35;
250
255
 
256
+ /** auto:真实数字/显式数值格式居右,日期与布尔居中,其他内容居左。 */
257
+ export declare type ListAlignment = NonNullable<ComponentStyle["align"]> | "auto";
258
+
251
259
  export declare interface ListColumn {
252
260
  header: string;
253
261
  field: string;
254
262
  widthMm: number;
255
263
  style?: ComponentStyle;
264
+ /** 内容对齐,优先于 style.align;数值字符串不会自动判为数字。 */
265
+ align?: ListAlignment;
266
+ /** 独立的表头对齐,不改变内容对齐。 */
267
+ headerAlign?: ComponentStyle["align"];
268
+ /** 独立的表头样式,优先于列表级表头样式。 */
269
+ headerStyle?: ComponentStyle;
256
270
  /** 值格式化(声明式):千分位/小数位、百分比、日期 pattern */
257
271
  format?: ColumnFormat;
258
272
  /** 条件格式规则(声明式,命中合并进单元格样式;如负数红字) */
@@ -262,6 +276,10 @@ export declare interface ListColumn {
262
276
  export declare interface ListComponent {
263
277
  kind: "list";
264
278
  id?: string;
279
+ /** 宽表标记用于连续 Excel;不改变低层列表的列宽和分页算法。 */
280
+ layout?: "page" | "wide";
281
+ /** 逻辑表名称,供 Excel Sheet 命名;不额外生成标题组件。 */
282
+ title?: string;
265
283
  leftMm: number;
266
284
  topMm: number;
267
285
  widthMm: number;
@@ -273,6 +291,11 @@ export declare interface ListComponent {
273
291
  paddingMm?: number;
274
292
  headerEveryPage?: boolean;
275
293
  headerBackgroundColor?: string;
294
+ /** 内容默认对齐,列配置可覆盖;低层模板缺省仍为 left。 */
295
+ align?: ListAlignment;
296
+ /** 表头默认对齐,列配置可覆盖。 */
297
+ headerAlign?: ComponentStyle["align"];
298
+ headerStyle?: ComponentStyle;
276
299
  border?: boolean;
277
300
  /** 分组小计(组头/组尾小计/组头防孤行) */
278
301
  groupBy?: ListGroupBy;
@@ -351,7 +374,7 @@ export declare interface PageWindowInput {
351
374
  viewportHeightPx: number;
352
375
  scrollTopPx: number;
353
376
  overscan?: number;
354
- /** 页间距(px)。占位高度按“每页高度+间距”累计,与 margin-bottom 布局一致;默认 0 */
377
+ /** 页间距(px),默认 0;与每页 margin-bottom 使用同一口径。 */
355
378
  gapPx?: number;
356
379
  }
357
380
 
@@ -380,6 +403,9 @@ export declare type PaperName = keyof typeof PAPER_SIZES;
380
403
  /** 日历日字符串 → 本地 Date(不含时间的纯日期,杜绝 UTC 偏移) */
381
404
  export declare function parseDateLocal(input: string): Date | null;
382
405
 
406
+ /** 校验文件 JSON 文本或接口返回的未知对象,返回独立模板快照。 */
407
+ export declare function parseReportTemplate(input: unknown): ReportTemplateDocument;
408
+
383
409
  export declare interface PlanComponent {
384
410
  kind: ComponentKind;
385
411
  leftMm: number;
@@ -394,6 +420,7 @@ export declare interface PlanComponent {
394
420
  richParagraphs?: RichParagraph[];
395
421
  imageData?: string;
396
422
  grid?: PlanGrid;
423
+ table?: PlanTableFragment;
397
424
  style?: ComponentStyle;
398
425
  meta?: Record<string, unknown>;
399
426
  /** MachReport 扩展字段:未知 kind 的兜底渲染标记 */
@@ -415,6 +442,8 @@ export declare interface PlanGrid {
415
442
  }
416
443
 
417
444
  export declare interface PlanPage {
445
+ /** wide 表示完整自然列宽;页面仅为预览的垂直窗口分段。 */
446
+ layout?: "page" | "wide";
418
447
  pageWidthMm: number;
419
448
  pageHeightMm: number;
420
449
  marginTopMm?: number;
@@ -424,6 +453,19 @@ export declare interface PlanPage {
424
453
  components: PlanComponent[];
425
454
  }
426
455
 
456
+ /** 列表的逻辑行来源;用于连续 Excel 重组,避免按文本猜测重复表头。 */
457
+ export declare interface PlanTableFragment {
458
+ /** 在整个计划中唯一的逻辑表身份;同一表的分页片段共享身份。 */
459
+ id: string;
460
+ /** 表头固定 -1;其余行(包括组头/小计/总计)从 0 连续递增。 */
461
+ rowIndex: number;
462
+ role: "header" | "body" | "group-header" | "subtotal" | "grand-total";
463
+ /** 按物理列顺序保存字段身份;不以表头显示文本判断列结构。 */
464
+ columnKeys: string[];
465
+ layout?: "page" | "wide";
466
+ title?: string;
467
+ }
468
+
427
469
  export declare function ptToPx(pt: number, dpi?: number): number;
428
470
 
429
471
  export declare function pxToMm(value: number, dpi?: number): number;
@@ -462,12 +504,16 @@ export declare function renderPlanToCanvas(plan: RenderPlan, options?: CanvasRen
462
504
  */
463
505
  export declare function renderPlanToImages(plan: RenderPlan, options?: ImageRenderOptions): Promise<ImageRenderResult>;
464
506
 
507
+ /** 模板存储文档版本;与渲染计划版本独立演进。 */
508
+ export declare const REPORT_TEMPLATE_DOCUMENT_VERSION: "1.0";
509
+
465
510
  export declare interface ReportDefinition {
466
- template: ReportTemplate;
511
+ /** 静态模板或宿主提供的异步模板加载器;动态模板默认每次重新读取,不缓存版本。 */
512
+ template: ReportTemplate | ReportTemplateLoader;
467
513
  /** 静态数据;load 存在时优先使用 load 的结果。 */
468
514
  datasets?: DatasetRows;
469
515
  load?: (context: ReportLoadContext) => DatasetRows | Promise<DatasetRows>;
470
- /** 覆盖模板参数定义,未提供时自动使用 template.params。 */
516
+ /** 覆盖模板参数定义;动态模板应在此声明查询面板元数据,避免查询前先请求模板。 */
471
517
  params?: ReportParamDef[];
472
518
  pagination?: PaginateOptions;
473
519
  }
@@ -534,6 +580,37 @@ export declare interface ReportTemplate {
534
580
  pages: TemplatePage[];
535
581
  }
536
582
 
583
+ /** 可存入数据库/文件的纯 JSON 模板;数据、接口与鉴权仍由宿主提供。 */
584
+ export declare interface ReportTemplateDocument {
585
+ schemaVersion: typeof REPORT_TEMPLATE_DOCUMENT_VERSION;
586
+ id: string;
587
+ name: string;
588
+ /** 宿主的发布版本/乐观锁标识,不由引擎自动递增。 */
589
+ revision?: string;
590
+ description?: string;
591
+ template: ReportTemplate;
592
+ }
593
+
594
+ export declare class ReportTemplateError extends Error {
595
+ readonly errors: readonly ValidationError[];
596
+ constructor(errors: readonly ValidationError[]);
597
+ }
598
+
599
+ export declare type ReportTemplateLoader = (context: ReportLoadContext) => ReportTemplate | Promise<ReportTemplate>;
600
+
601
+ export declare interface ReportTemplateRegistry {
602
+ /** 返回独立快照,调用方编辑不会改变目录中的已注册模板。 */
603
+ get(id: string): ReportTemplateDocument | undefined;
604
+ list(): ReportTemplateSummary[];
605
+ /** 重复 ID 默认拒绝;更新必须显式 replace:true。 */
606
+ register(document: ReportTemplateDocument, options?: {
607
+ replace?: boolean;
608
+ }): void;
609
+ remove(id: string): boolean;
610
+ }
611
+
612
+ export declare type ReportTemplateSummary = Omit<ReportTemplateDocument, "template">;
613
+
537
614
  /**
538
615
  * 边框开关解析:
539
616
  * - 未声明(undefined)→ 四边全开(与既有 rect 总有边框的行为兼容)
@@ -604,6 +681,9 @@ export declare function round(value: number, digits: number): number;
604
681
  /** RenderPlan 正式 schema 版本(core 分页引擎产出) */
605
682
  export declare const SCHEMA_VERSION_MACH = "1.0.0-mach";
606
683
 
684
+ /** 格式化输出已校验的纯模板 JSON,不静默丢弃函数或非法数字。 */
685
+ export declare function serializeReportTemplate(document: ReportTemplateDocument): string;
686
+
607
687
  /** 条件格式规则求值(声明式,见 ListColumn.rules) */
608
688
  export declare interface StyleRule {
609
689
  when: {
@@ -615,16 +695,20 @@ export declare interface StyleRule {
615
695
  style: Record<string, unknown>;
616
696
  }
617
697
 
618
- /** 标准明细列:显式 widthMm 优先;其余列按 flex 分配剩余可用宽度。 */
698
+ /** 明细列:显式 widthMm 优先;纸张模式按 flex 分余量,宽表模式按 flex 放大基准列宽。 */
619
699
  export declare type TableTemplateColumn = Omit<ListColumn, "widthMm"> & {
620
700
  widthMm?: number;
621
701
  /** 自动列的宽度权重,默认 1(有 widthMm 时不参与分配)。 */
622
702
  flex?: number;
623
703
  };
624
704
 
625
- export declare type TableTemplateListOptions = Partial<Omit<ListComponent, "kind" | "leftMm" | "topMm" | "widthMm" | "dataset" | "columns">>;
705
+ export declare type TableTemplateListOptions = Partial<Omit<ListComponent, "kind" | "leftMm" | "topMm" | "widthMm" | "dataset" | "columns" | "layout" | "title">>;
626
706
 
627
707
  export declare interface TableTemplateOptions extends PageOptions {
708
+ /** page 保持旧版纸张布局;wide 按所有列的自然宽度扩展,纵向分段仅供预览与渲染。 */
709
+ layout?: "page" | "wide";
710
+ /** 宽表模式自动列的基准宽度,默认 30mm;widthMm 优先,flex 为基准宽度的倍数。 */
711
+ columnWidthMm?: number;
628
712
  title?: string;
629
713
  /** 标题占高,默认 10mm;没有标题时不占空间。 */
630
714
  titleHeightMm?: number;
@@ -633,7 +717,7 @@ export declare interface TableTemplateOptions extends PageOptions {
633
717
  titleStyle?: ComponentStyle;
634
718
  dataset?: string;
635
719
  columns: readonly TableTemplateColumn[];
636
- /** 默认 A4;页边距各默认 10mm。 */
720
+ /** 纸张模式默认 A4;与 layout: "wide" 互斥;页边距各默认 10mm。 */
637
721
  paper?: PaperName | {
638
722
  widthMm: number;
639
723
  heightMm: number;
@@ -681,6 +765,8 @@ export declare type TemplateComponent = PlanComponent | ListComponent;
681
765
  export declare interface TemplatePage {
682
766
  widthMm: number;
683
767
  heightMm: number;
768
+ /** 宽表保持全列自然宽度,页高只控制内部纵向分段。 */
769
+ layout?: "page" | "wide";
684
770
  marginTopMm?: number;
685
771
  marginBottomMm?: number;
686
772
  marginLeftMm?: number;
@@ -706,6 +792,9 @@ export declare interface TextMeasurer {
706
792
  measureMm(text: string, options: TextMeasureOptions): number;
707
793
  }
708
794
 
795
+ /** 数值型 Excel 导出的显示格式;日期/对象仍使用显示文本,不做隐式类型转换。 */
796
+ export declare function toExcelNumberFormat(format?: ColumnFormat): string | undefined;
797
+
709
798
  export declare function toNumber(value: unknown): number | null;
710
799
 
711
800
  export declare function validateComponent(comp: unknown, path: string, errors: ValidationError[], warnings?: ValidationError[]): void;
@@ -714,6 +803,11 @@ export declare function validatePage(page: unknown, path: string, errors: Valida
714
803
 
715
804
  export declare function validateRenderPlan(input: unknown): ValidationResult;
716
805
 
806
+ /** 对入库/导入模板做声明式校验,不执行分页或数据请求。 */
807
+ export declare function validateReportTemplate(input: unknown): ValidationResult;
808
+
809
+ export declare function validateReportTemplateDocument(input: unknown): ValidationResult;
810
+
717
811
  export declare interface ValidationError {
718
812
  path: string;
719
813
  message: string;