@agile-team/mach-report 2.0.0 → 2.1.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 (77) hide show
  1. package/LICENSE +2 -4
  2. package/LICENSING.md +15 -0
  3. package/README.md +232 -76
  4. package/dist/ReportPreview-Dwdsyk9b.js +1558 -0
  5. package/dist/ReportPreview-VHAIfsz1.cjs +6 -0
  6. package/dist/index.cjs +5 -5
  7. package/dist/index.d.cts +738 -13
  8. package/dist/index.d.ts +738 -13
  9. package/dist/index.js +821 -631
  10. package/dist/pdf.cjs +47 -47
  11. package/dist/pdf.d.cts +155 -6
  12. package/dist/pdf.d.ts +155 -6
  13. package/dist/pdf.js +3542 -3466
  14. package/dist/plugin-Bl00j_CP.cjs +1 -0
  15. package/dist/plugin-DVScnZ4C.js +25 -0
  16. package/dist/report-params-BB85g7mg.js +10 -0
  17. package/dist/report-params-D1NeY-eR.cjs +1 -0
  18. package/dist/sql.cjs +65 -64
  19. package/dist/sql.d.cts +109 -5
  20. package/dist/sql.d.ts +109 -5
  21. package/dist/sql.js +7947 -7922
  22. package/dist/style.css +1 -1
  23. package/dist/vue/async.d.cts +769 -320
  24. package/dist/vue/async.d.ts +769 -320
  25. package/dist/vue/index.d.cts +1321 -14
  26. package/dist/vue/index.d.ts +1321 -14
  27. package/dist/vue-async.cjs +1 -1
  28. package/dist/vue-async.js +11 -12
  29. package/dist/vue.cjs +1 -1
  30. package/dist/vue.js +129 -49
  31. package/dist/xlsx.cjs +20 -20
  32. package/dist/xlsx.d.cts +2292 -5
  33. package/dist/xlsx.d.ts +2292 -5
  34. package/dist/xlsx.js +5452 -5443
  35. package/package.json +6 -2
  36. package/dist/ReportPreview-Cr0IH1Rz.cjs +0 -6
  37. package/dist/ReportPreview-DwknBgsJ.js +0 -1266
  38. package/dist/builder/template-builder.d.ts +0 -69
  39. package/dist/defaults.d.ts +0 -23
  40. package/dist/format.d.ts +0 -48
  41. package/dist/layout/paginate.d.ts +0 -97
  42. package/dist/layout/textwrap.d.ts +0 -36
  43. package/dist/pdf/font-loader.d.ts +0 -6
  44. package/dist/pdf/index.d.ts +0 -2
  45. package/dist/pdf/render-pdf.d.ts +0 -25
  46. package/dist/plugin-Cj3c2wJc.cjs +0 -1
  47. package/dist/plugin-DJf_6_fl.js +0 -18
  48. package/dist/render/canvas.d.ts +0 -76
  49. package/dist/render/dom.d.ts +0 -10
  50. package/dist/render/grid-geometry.d.ts +0 -41
  51. package/dist/render/style.d.ts +0 -33
  52. package/dist/render/window.d.ts +0 -23
  53. package/dist/schema/render-plan.d.ts +0 -88
  54. package/dist/schema/validate.d.ts +0 -15
  55. package/dist/sql/ast-check.d.ts +0 -14
  56. package/dist/sql/compile.d.ts +0 -31
  57. package/dist/sql/expr.d.ts +0 -21
  58. package/dist/sql/index.d.ts +0 -4
  59. package/dist/sql/tokenizer.d.ts +0 -25
  60. package/dist/units.d.ts +0 -11
  61. package/dist/vue/ReportParamPanel.d.ts +0 -19
  62. package/dist/vue/ReportPreview.d.ts +0 -200
  63. package/dist/vue/ReportToolbar.d.ts +0 -42
  64. package/dist/vue/adapters.d.ts +0 -34
  65. package/dist/vue/composables/useHighlight.d.ts +0 -8
  66. package/dist/vue/composables/usePageWindow.d.ts +0 -25
  67. package/dist/vue/composables/usePrintExport.d.ts +0 -40
  68. package/dist/vue/composables/useReportSearch.d.ts +0 -73
  69. package/dist/vue/composables/useZoom.d.ts +0 -15
  70. package/dist/vue/config.d.ts +0 -108
  71. package/dist/vue/controller.d.ts +0 -29
  72. package/dist/vue/errors.d.ts +0 -16
  73. package/dist/vue/injection-keys.d.ts +0 -14
  74. package/dist/vue/local-adapter.d.ts +0 -11
  75. package/dist/vue/pdf-exporter.d.ts +0 -13
  76. package/dist/vue/plugin.d.ts +0 -332
  77. package/dist/xlsx/render-xlsx.d.ts +0 -20
@@ -1,69 +0,0 @@
1
- import { ListColumn, ListComponent, ReportTemplate, TemplatePage } from '../layout/paginate';
2
- import { ComponentStyle, PlanComponent } from '../schema/render-plan';
3
- import { PAPER_SIZES } from '../units';
4
- type Geometry = Partial<Pick<PlanComponent, "leftMm" | "topMm" | "widthMm" | "heightMm">>;
5
- /** 纸张预设名(对齐 PAPER_SIZES 表) */
6
- export type PaperName = keyof typeof PAPER_SIZES;
7
- export interface PageOptions {
8
- /** 横向(宽高互换) */
9
- landscape?: boolean;
10
- margins?: Partial<Pick<TemplatePage, "marginTopMm" | "marginBottomMm" | "marginLeftMm" | "marginRightMm">>;
11
- }
12
- type PageMargins = Partial<Pick<TemplatePage, "marginTopMm" | "marginBottomMm" | "marginLeftMm" | "marginRightMm">>;
13
- /** 解析纸张参数:数字按宽高使用;字符串查 PAPER_SIZES 预设;缺省 A4 纵向 */
14
- export declare function resolvePaper(paper: PaperName | {
15
- widthMm: number;
16
- heightMm: number;
17
- } | number, heightArg?: number, landscape?: boolean): {
18
- widthMm: number;
19
- heightMm: number;
20
- };
21
- export declare class TemplateBuilder {
22
- readonly pages: TemplatePage[];
23
- private pending;
24
- private templateParams;
25
- /**
26
- * 声明报表参数(链式,可放在 .page() 前后任意位置):
27
- * 渲染组件据此自动生成查询面板(也可由 paramDefs prop 提供,prop 优先)。
28
- *
29
- * ```ts
30
- * createTemplate()
31
- * .params([
32
- * { field: "whCode", label: "仓库", type: "select", options: [...], required: true },
33
- * { field: "date", label: "日期", type: "date", defaultValue: "2026-09-30" }
34
- * ])
35
- * .page("a4").text(...).list(...)
36
- * .build();
37
- * ```
38
- */
39
- params(defs: NonNullable<ReportTemplate["params"]>): this;
40
- /**
41
- * 新建页。纸张支持三种写法:
42
- * - 预设名:.page("a4", { landscape: true, margins: {...} })
43
- * - 数字:.page(210, 297)(第三参数兼容旧 margins 对象或新 options)
44
- * - 对象:.page({ widthMm: 210, heightMm: 297 })
45
- */
46
- page(paper?: PaperName | {
47
- widthMm: number;
48
- heightMm: number;
49
- } | number, optionsOrHeight?: number | PageOptions, maybeOptions?: PageOptions | PageMargins): PageBuilder;
50
- collect(): void;
51
- build(): ReportTemplate;
52
- }
53
- export declare class PageBuilder {
54
- private readonly parent;
55
- private readonly page;
56
- private components;
57
- constructor(parent: TemplateBuilder, page: Omit<TemplatePage, "components">);
58
- text(content: string, geometry?: Geometry, style?: ComponentStyle): this;
59
- list(dataset: string, geometry: Partial<Pick<ListComponent, "leftMm" | "topMm" | "widthMm">>, columns: ListColumn[], options?: Partial<Omit<ListComponent, "kind" | "leftMm" | "topMm" | "widthMm" | "dataset" | "columns">>): this;
60
- rect(geometry: Required<Pick<PlanComponent, "leftMm" | "topMm" | "widthMm" | "heightMm">>, style?: ComponentStyle): this;
61
- line(leftMm: number, topMm: number, widthMm: number, style?: ComponentStyle): this;
62
- barcode(content: string, geometry: Required<Geometry>): this;
63
- qrcode(content: string, sizeMm: number, leftMm: number, topMm: number): this;
64
- buildPage(): TemplatePage;
65
- done(): TemplateBuilder;
66
- build(): ReportTemplate;
67
- }
68
- export declare function createTemplate(): TemplateBuilder;
69
- export {};
@@ -1,23 +0,0 @@
1
- /**
2
- * 全引擎共享默认值(唯一真相源)。
3
- *
4
- * 修改这里的任何常量前请注意消费方:
5
- * - LINE_HEIGHT:分页行高估算 / Canvas / PDF 三处换算必须一致
6
- * - DEFAULT_FONT_PT / DEFAULT_BORDER_PT:三后端默认字号与线宽
7
- * - SCHEMA_VERSION_*:RenderPlan 版本标识(adapter 产出侧使用)
8
- *
9
- * 历史:这些值曾散落在 paginate/canvas/pdf/dom 四个文件中各写一份,
10
- * 是三后端漂移的温床,收敛于此。
11
- */
12
- /** 默认行高倍数(基线距 = 字号 × 该系数) */
13
- export declare const LINE_HEIGHT = 1.35;
14
- /** 默认字号(pt) */
15
- export declare const DEFAULT_FONT_PT = 10.5;
16
- /** 默认边框线宽(pt) */
17
- export declare const DEFAULT_BORDER_PT = 0.75;
18
- /** 默认描边色 */
19
- export declare const DEFAULT_STROKE_COLOR = "#333333";
20
- /** 默认文本色 */
21
- export declare const DEFAULT_TEXT_COLOR = "#000000";
22
- /** RenderPlan 正式 schema 版本(core 分页引擎产出) */
23
- export declare const SCHEMA_VERSION_MACH = "1.0.0-mach";
package/dist/format.d.ts DELETED
@@ -1,48 +0,0 @@
1
- /**
2
- * 列值格式化(声明式、JSON 可序列化)。
3
- * 在 paginate 的 cellText 出口统一消费:格式化发生在进 RenderPlan 之前,
4
- * 三后端(DOM/Canvas/PDF)零改动。
5
- *
6
- * 语义约定(v0.9 固化):
7
- * - number.digits 显式给出 → 精确保留(12.5 + digits:2 → "12.50")
8
- * - number.thousands 默认 false(千分位显式开启)
9
- * - date 字符串按"本地时区的日历日"解析(YYYY-MM-DD / YYYY/MM/DD 直取年月日,
10
- * 不经 Date 字符串构造——后者按 UTC 零点,负时区环境会少一天)
11
- */
12
- export type ColumnFormat = {
13
- kind: "number";
14
- thousands?: boolean;
15
- digits?: number;
16
- } | {
17
- kind: "percent";
18
- digits?: number;
19
- } | {
20
- kind: "date";
21
- pattern?: string;
22
- };
23
- /** 日历日字符串 → 本地 Date(不含时间的纯日期,杜绝 UTC 偏移) */
24
- export declare function parseDateLocal(input: string): Date | null;
25
- export declare function toNumber(value: unknown): number | null;
26
- /**
27
- * 应用格式化。非数值/无法解析时原样返回基础文本(降级不报错):
28
- * - number:digits 小数位 + 可选千分位(12,345.60;thousands 默认 false)
29
- * - percent:×100 + % 后缀(digits 默认 2)
30
- * - date:Date/日历日字符串 → pattern(默认 YYYY-MM-DD);不可解析原样返回
31
- */
32
- export declare function formatValue(value: unknown, format?: ColumnFormat): string;
33
- /** 条件格式规则求值(声明式,见 ListColumn.rules) */
34
- export interface StyleRule {
35
- when: {
36
- field: string;
37
- op: ">" | ">=" | "<" | "<=" | "==" | "!=";
38
- value: number | string;
39
- };
40
- /** 命中时合并进单元格样式(color/bold/backgroundColor 等) */
41
- style: Record<string, unknown>;
42
- }
43
- /**
44
- * 规则求值语义:
45
- * - 空值(null/undefined/"")永不命中(避免 Number("")===0 把空当 0 的隐式陷阱)
46
- * - 数值比较:两侧均可数值化才比较;否则退化为字符串比较
47
- */
48
- export declare function evalStyleRule(row: Record<string, unknown>, when: StyleRule["when"]): boolean;
@@ -1,97 +0,0 @@
1
- import { ComponentStyle, PlanComponent, RenderPlan } from '../schema/render-plan';
2
- import { TextMeasurer } from './textwrap';
3
- import { ColumnFormat, StyleRule } from '../format';
4
- export interface ListColumn {
5
- header: string;
6
- field: string;
7
- widthMm: number;
8
- style?: ComponentStyle;
9
- /** 值格式化(声明式):千分位/小数位、百分比、日期 pattern */
10
- format?: ColumnFormat;
11
- /** 条件格式规则(声明式,命中合并进单元格样式;如负数红字) */
12
- rules?: StyleRule[];
13
- }
14
- /** 分组小计配置(声明式,见 ListComponent.groupBy) */
15
- export interface ListGroupBy {
16
- /** 分组字段(值变化即切组) */
17
- field: string;
18
- /** 组头文案模板,{value} 占位(默认 "{value}") */
19
- headerTemplate?: string;
20
- headerStyle?: ComponentStyle;
21
- /** 需要小计的列字段(组尾输出合计行;数值列求和,其余输出首值/留空) */
22
- subtotal?: string[];
23
- subtotalStyle?: ComponentStyle;
24
- subtotalLabel?: string;
25
- /** 组头防孤行(默认 true:页尾放不下"组头+首行"时整体换页) */
26
- keepWithNext?: boolean;
27
- }
28
- export type ListGrandTotal = boolean | {
29
- label?: string;
30
- style?: ComponentStyle;
31
- /** 合计列(缺省沿用 groupBy.subtotal) */
32
- fields?: string[];
33
- };
34
- export interface ListComponent {
35
- kind: "list";
36
- id?: string;
37
- leftMm: number;
38
- topMm: number;
39
- widthMm: number;
40
- dataset: string;
41
- columns: ListColumn[];
42
- fontSizePt?: number;
43
- headerBold?: boolean;
44
- rowHeightMm?: number;
45
- paddingMm?: number;
46
- headerEveryPage?: boolean;
47
- headerBackgroundColor?: string;
48
- border?: boolean;
49
- /** 分组小计(组头/组尾小计/组头防孤行) */
50
- groupBy?: ListGroupBy;
51
- /** 末尾总合计行(依赖 groupBy.subtotal 或显式 fields) */
52
- grandTotal?: ListGrandTotal;
53
- }
54
- export type TemplateComponent = PlanComponent | ListComponent;
55
- export interface TemplatePage {
56
- widthMm: number;
57
- heightMm: number;
58
- marginTopMm?: number;
59
- marginBottomMm?: number;
60
- marginLeftMm?: number;
61
- marginRightMm?: number;
62
- components: TemplateComponent[];
63
- }
64
- /** 报表参数定义(声明式,模板自描述参数面:渲染组件据此生成查询面板) */
65
- export interface ReportParamDef {
66
- /** 参数名(传入 params,与数据集 SQL #{field} 绑定对应) */
67
- field: string;
68
- /** 显示名(缺省用 field) */
69
- label?: string;
70
- type?: "text" | "number" | "date" | "select";
71
- /** select 选项 */
72
- options?: Array<{
73
- label: string;
74
- value: string;
75
- }>;
76
- defaultValue?: string;
77
- required?: boolean;
78
- placeholder?: string;
79
- }
80
- export interface ReportTemplate {
81
- schemaVersion?: string;
82
- /** 参数定义(可选;宿主也可经 ReportPreview 的 paramDefs prop 提供,prop 优先) */
83
- params?: ReportParamDef[];
84
- pages: TemplatePage[];
85
- }
86
- export type DatasetRows = Record<string, Record<string, unknown>[]>;
87
- export interface PaginateOptions {
88
- /** 每行额外占高(mm),压测专用钩子 */
89
- mmPerRow?: number;
90
- /** 文本测量器(默认启发式;浏览器端可注入 canvas 测量校准) */
91
- measurer?: TextMeasurer;
92
- }
93
- export interface PaginateResult {
94
- plan: RenderPlan;
95
- warnings: string[];
96
- }
97
- export declare function paginateTemplate(template: ReportTemplate, datasets: DatasetRows, optionsOrMmPerRow?: number | PaginateOptions): PaginateResult;
@@ -1,36 +0,0 @@
1
- /**
2
- * 文本测量与折行(分页/Canvas/PDF 共用的唯一折行真相源)。
3
- *
4
- * 测量模型可注入(TextMeasurer):
5
- * - 默认 createHeuristicMeasurer():CJK/拉丁宽度启发式(零依赖、Node 可用)
6
- * - 浏览器端可注入 createCanvasMeasurer()(真字体 metrics,消除三端折行差异)
7
- */
8
- export interface TextMeasureOptions {
9
- fontSizePt: number;
10
- bold?: boolean;
11
- letterSpacingPt?: number;
12
- }
13
- /** 宽度测量接口:返回文本在给定字号下的宽度(mm)。实现必须无副作用、可缓存。 */
14
- export interface TextMeasurer {
15
- measureMm(text: string, options: TextMeasureOptions): number;
16
- }
17
- export declare function charWidthEm(ch: string): number;
18
- /** 启发式测量器:无 Canvas 时的默认宽度估算 */
19
- export declare const heuristicMeasurer: TextMeasurer;
20
- /** 兼容旧 API:默认启发式测量 */
21
- export declare function createHeuristicMeasurer(): TextMeasurer;
22
- export declare function measureTextMm(text: string, options: TextMeasureOptions): number;
23
- /**
24
- * 浏览器 Canvas 测量器:用真实字体 metrics 校准宽度(可选注入)。
25
- * 无 2D 环境时自动回退启发式(Node/SSR 安全)。
26
- */
27
- export declare function createCanvasMeasurer(getCtx2d: () => CanvasRenderingContext2D | null): TextMeasurer;
28
- /**
29
- * 文本折行:
30
- * - CJK 字符任意位置可断(与既有行为一致)
31
- * - 连续拉丁/数字串视为一个词,仅在词间(空格/CJK 边界)断行;
32
- * 单词本身超宽时按字符硬拆(兜底,不无限溢出)
33
- * - 换行符强制断行;行首不保留折行产生的空格
34
- * - 可注入 TextMeasurer(默认启发式)
35
- */
36
- export declare function wrapText(text: string, maxWidthMm: number, options: TextMeasureOptions, measurer?: TextMeasurer): string[];
@@ -1,6 +0,0 @@
1
- /**
2
- * 字体加载(浏览器:IndexedDB 持久缓存 + 内存缓存;Node/SSR:内存缓存 + fetch):
3
- * 中文字体体积大(simhei ~9MB),首次 fetch 后缓存,后续导出零网络等待。
4
- * 双环境兼容——同一引擎可在 Node 做无头导出(定时任务/归档)。
5
- */
6
- export declare function loadFontWithCache(url: string): Promise<Uint8Array | null>;
@@ -1,2 +0,0 @@
1
- export * from './render-pdf';
2
- export * from './font-loader';
@@ -1,25 +0,0 @@
1
- import { RenderPlan } from '../schema/render-plan';
2
- import { TextMeasurer } from '../index';
3
- export interface PdfRenderOptions {
4
- /** 嵌入字体字节(TTF,如黑体);缺省用 Helvetica(不支持 CJK) */
5
- customFontBytes?: Uint8Array | ArrayBuffer;
6
- customFontName?: string;
7
- /** 文本测量器(默认启发式;与分页/Canvas 注入同一实例可消除折行差异) */
8
- measurer?: TextMeasurer;
9
- }
10
- /**
11
- * PDF 文档句柄(不透明最小面):结构化仅暴露 save(),
12
- * 避免在公共类型面泄漏 pdf-lib 类型(引擎保持零运行时依赖声明)。
13
- */
14
- export type PdfDocumentHandle = {
15
- save(): Promise<Uint8Array>;
16
- };
17
- export interface PdfRenderResult {
18
- pdfDoc: PdfDocumentHandle;
19
- bytes: Uint8Array;
20
- pageErrors: string[];
21
- unsupportedTextCount: number;
22
- /** 保真度降级清单(富文本转纯文本、图片格式不支持等),供上层提示 */
23
- fidelityWarnings: string[];
24
- }
25
- export declare function renderPlanToPdf(plan: RenderPlan, options?: PdfRenderOptions): Promise<PdfRenderResult>;
@@ -1 +0,0 @@
1
- "use strict";const R=require("vue"),c="mach-report/fetcher",o="mach-report/pdf-exporter",E="mach-report/config",n="mach-report/controller",_=R.defineAsyncComponent(()=>Promise.resolve().then(()=>require("./ReportPreview-Cr0IH1Rz.cjs")).then(r=>r.ReportPreview$1)),f={install(r,e={}){e.fetcher&&r.provide(c,e.fetcher),e.pdfExporter&&r.provide(o,e.pdfExporter),r.provide(E,R.computed(()=>{if(e.pdfFontUrl===void 0)return e.config??null;const t=e.config??{defaults:{},presets:{}};return{...t,defaults:{...t.defaults,pdfFontUrl:e.pdfFontUrl}}})),e.globalComponent!==!1&&r.component("MachReportPreview",_)}};exports.MACH_REPORT_CONFIG_KEY=E;exports.MACH_REPORT_CONTROLLER_KEY=n;exports.MACH_REPORT_FETCHER_KEY=c;exports.MACH_REPORT_PDF_EXPORTER_KEY=o;exports.MachReportPreview=_;exports.machReportPlugin=f;
@@ -1,18 +0,0 @@
1
- import { defineAsyncComponent as c, computed as o } from "vue";
2
- const f = "mach-report/fetcher", n = "mach-report/pdf-exporter", a = "mach-report/config", R = "mach-report/controller", d = c(() => import("./ReportPreview-DwknBgsJ.js").then((r) => r.s)), E = {
3
- install(r, e = {}) {
4
- e.fetcher && r.provide(f, e.fetcher), e.pdfExporter && r.provide(n, e.pdfExporter), r.provide(a, o(() => {
5
- if (e.pdfFontUrl === void 0) return e.config ?? null;
6
- const t = e.config ?? { defaults: {}, presets: {} };
7
- return { ...t, defaults: { ...t.defaults, pdfFontUrl: e.pdfFontUrl } };
8
- })), e.globalComponent !== !1 && r.component("MachReportPreview", d);
9
- }
10
- };
11
- export {
12
- R as M,
13
- a,
14
- f as b,
15
- n as c,
16
- d,
17
- E as m
18
- };
@@ -1,76 +0,0 @@
1
- import { PlanPage, RenderPlan } from '../schema/render-plan';
2
- import { TextMeasurer } from '../layout/textwrap';
3
- export interface CanvasRenderOptions {
4
- /** 设备像素比,默认取运行环境 devicePixelRatio */
5
- dpr?: number;
6
- dpi?: number;
7
- /** 文本默认字体族 */
8
- fontFamily?: string;
9
- /** 文本测量器(默认启发式) */
10
- measurer?: TextMeasurer;
11
- /** 只渲染页区间(闭区间索引;缺省全渲染——仅小报表使用,大报表请用 createCanvasPager) */
12
- start?: number;
13
- end?: number;
14
- }
15
- export declare function measurePageSizePx(page: Pick<PlanPage, "pageWidthMm" | "pageHeightMm">, dpi?: number): {
16
- widthPx: number;
17
- heightPx: number;
18
- };
19
- /** pt→px 换算(与 DOM 后端 units.ptToPx 同一真相源),供单测直接断言 */
20
- export declare function planFontSizePx(style: {
21
- fontSizePx?: number;
22
- fontSize?: number;
23
- } | undefined, dpi?: number): number;
24
- export interface CanvasRenderResult {
25
- canvases: HTMLCanvasElement[];
26
- }
27
- export interface ImageRenderOptions extends CanvasRenderOptions {
28
- /** 图片格式(默认 png;jpeg 体积更小但无透明) */
29
- format?: "png" | "jpeg";
30
- /** jpeg 质量 0-1(默认 0.92,仅 jpeg 生效) */
31
- quality?: number;
32
- }
33
- export interface ImageRenderResult {
34
- blobs: Blob[];
35
- }
36
- /**
37
- * RenderPlan → 每页一张图片 Blob(浏览器环境):
38
- * 复用位图渲染管线(区间/dpr/字体/测量器均可配),再 toBlob 编码。
39
- * 大报表建议配合 start/end 分批导出,避免一次性占用过多内存。
40
- */
41
- export declare function renderPlanToImages(plan: RenderPlan, options?: ImageRenderOptions): Promise<ImageRenderResult>;
42
- /**
43
- * RenderPlan → Canvas 位图页(顶点原点坐标系,与 DOM/PDF 一致)。
44
- *
45
- * ⚠️ 内存模型:A4 @dpr2 ≈ 14MB/页,全量渲染 100 页 ≈ 1.4GB。
46
- * 大报表必须使用 createCanvasPager(窗口化 + 画布池 + 分帧渲染),
47
- * 本函数适合页数少或已指定 start/end 区间的场景。
48
- */
49
- export declare function renderPlanToCanvas(plan: RenderPlan, options?: CanvasRenderOptions): CanvasRenderResult;
50
- export interface CanvasPagerOptions extends CanvasRenderOptions {
51
- /** 预渲染页数缓冲(窗口两侧各加 N 页),默认 1 */
52
- overscan?: number;
53
- /** 页间距 px,默认 18 */
54
- gapPx?: number;
55
- /** 每帧渲染页数上限(分帧,防长任务),默认 1 */
56
- pagesPerFrame?: number;
57
- }
58
- export interface CanvasPager {
59
- /** 挂载到滚动容器(viewport,overflow:auto),接管其内容 */
60
- attach(viewport: HTMLElement): void;
61
- destroy(): void;
62
- /** 当前实际渲染的页区间 */
63
- window(): {
64
- start: number;
65
- end: number;
66
- };
67
- }
68
- /**
69
- * Canvas 虚拟化分页器(大报表专用):
70
- * - 视口窗口化:只绘制窗口内页(computePageWindow 与 DOM 后端共用)
71
- * - 画布池:固定数量 canvas 复用重绘,滚动零新增位图
72
- * - 分帧:每帧最多 pagesPerFrame 页,滚动期间不产生长任务
73
- *
74
- * 内存从 O(总页数) 降到 O(窗口+2×overscan)。
75
- */
76
- export declare function createCanvasPager(plan: RenderPlan, options?: CanvasPagerOptions): CanvasPager;
@@ -1,10 +0,0 @@
1
- import { PlanComponent, PlanPage, RenderPlan } from '../schema/render-plan';
2
- export interface RenderOptions {
3
- dpi?: number;
4
- classNames?: Partial<Record<ClassKey, string>>;
5
- }
6
- export type ClassKey = "root" | "page" | "comp" | "text" | "lines" | "line" | "rich" | "paragraph" | "segment" | "image" | "shape" | "grid" | "row" | "cell" | "unknown";
7
- export declare function classOf(key: ClassKey, options?: RenderOptions): string;
8
- export declare function renderComponent(comp: PlanComponent, dpi: number, options: RenderOptions, doc: Document): HTMLElement;
9
- export declare function renderPage(page: PlanPage, dpi: number, options: RenderOptions, doc: Document): HTMLElement;
10
- export declare function renderPlan(plan: RenderPlan, doc: Document, options?: RenderOptions): HTMLElement;
@@ -1,41 +0,0 @@
1
- import { GridCell, PlanGrid } from '../schema/render-plan';
2
- export interface GridCellBox {
3
- ri: number;
4
- ci: number;
5
- cell: GridCell;
6
- /** 相对组件左上角(mm,顶点原点) */
7
- xMm: number;
8
- yMm: number;
9
- widthMm: number;
10
- heightMm: number;
11
- }
12
- /** 网格线段:kind="h" 为水平线(pos=y,from/to=x 区间);"v" 为垂直线(pos=x,from/to=y 区间) */
13
- export interface GridEdge {
14
- kind: "h" | "v";
15
- pos: number;
16
- from: number;
17
- to: number;
18
- }
19
- export interface GridLayout {
20
- columns: {
21
- pos: number;
22
- size: number;
23
- }[];
24
- rows: {
25
- pos: number;
26
- size: number;
27
- }[];
28
- cells: GridCellBox[];
29
- /** 内部网格线段(不含外框;已跳过被 colSpan/rowSpan 跨越的边界,相邻段已合并) */
30
- edges: GridEdge[];
31
- }
32
- /**
33
- * 网格几何统一解析(DOM/Canvas/PDF 三后端共用,单位真相源):
34
- * - 列宽:优先 colWidthsMm(等比缩放至组件宽),否则按列数均分
35
- * - 行高:优先 rowHeightsMm(等比缩放至组件高),否则按行数均分
36
- * - colSpan/rowSpan:占位矩阵展开,跨度取起止行列差;越界收敛到网格内
37
- * - 行内 null/undefined 单元格视为占 1 列的空单元格(与 DOM 表格行为一致)
38
- * - edges:内部网格线段,跳过被 span 跨越的边界(合并单元格中间无线)
39
- * 产出为组件左上角顶点原点的 mm 坐标,各后端自行换算 px/pt。
40
- */
41
- export declare function resolveGridLayout(grid: PlanGrid, compWidthMm: number, compHeightMm: number): GridLayout;
@@ -1,33 +0,0 @@
1
- import { ComponentStyle } from '../schema/render-plan';
2
- /** 解析后的字号(px 值已按 dpi 换算;pt 值供 PDF 使用) */
3
- export interface ResolvedFontSize {
4
- fontSizePt: number;
5
- fontSizePx: number;
6
- }
7
- /** 字号解析:fontSizePx 直通;否则 pt→px(与 units.ptToPx 同源) */
8
- export declare function resolveFontSize(style: Pick<ComponentStyle, "fontSizePx" | "fontSize"> | undefined, dpi?: number, defaultPt?: number): ResolvedFontSize;
9
- /** 描边解析:颜色 + 线宽(pt) */
10
- export declare function resolveStroke(style: Pick<ComponentStyle, "borderColor" | "lineColor" | "lineWidthPt"> | undefined, fallbackColor?: string): {
11
- color: string;
12
- widthPt: number;
13
- };
14
- /** 文本颜色解析 */
15
- export declare function resolveTextColor(style: Pick<ComponentStyle, "color"> | undefined, fallback?: string): string;
16
- /** 行高解析(倍数,基线距 = 字号 × lineHeight) */
17
- export declare function resolveLineHeight(style: Pick<ComponentStyle, "lineHeight"> | undefined): number;
18
- /** 盒子边框语义:四边开关 + 内部网格线(四边全关则内线不画) */
19
- export interface BoxBorders {
20
- top: boolean;
21
- right: boolean;
22
- bottom: boolean;
23
- left: boolean;
24
- /** 网格内线(仅当任意外边开启) */
25
- inner: boolean;
26
- }
27
- /**
28
- * 边框开关解析:
29
- * - 未声明(undefined)→ 四边全开(与既有 rect 总有边框的行为兼容)
30
- * - 显式 false → 对应边关闭
31
- * - 四边全关(如 list border:false)→ 内线也不画
32
- */
33
- export declare function resolveBoxBorders(style: Pick<ComponentStyle, "borderTop" | "borderRight" | "borderBottom" | "borderLeft"> | undefined): BoxBorders;
@@ -1,23 +0,0 @@
1
- export interface PageWindowInput {
2
- pageHeightsPx: number[];
3
- viewportHeightPx: number;
4
- scrollTopPx: number;
5
- overscan?: number;
6
- /** 页间距(px)。占位高度按“每页高度+间距”累计,与 margin-bottom 布局一致;默认 0 */
7
- gapPx?: number;
8
- }
9
- export interface PageWindow {
10
- start: number;
11
- end: number;
12
- padTopPx: number;
13
- padBottomPx: number;
14
- }
15
- /**
16
- * 页级视口虚拟化:给定每页高度与滚动位置,返回需要真实渲染的页区间
17
- * 与上下占位高度。start/end 为闭区间索引。
18
- *
19
- * 布局模型:每页占据 height + gap(gap 为页间距,默认 0),
20
- * padTop/padBottom 同口径累计,保证 占位+渲染页+间距 还原总滚动高度。
21
- * 内部用前缀和 + 二分定位覆盖页与可见终点。
22
- */
23
- export declare function computePageWindow(input: PageWindowInput): PageWindow;
@@ -1,88 +0,0 @@
1
- export type ComponentKind = "text" | "image" | "barcode" | "qrcode" | "chart" | "line" | "rect" | "ellipse";
2
- export interface ComponentStyle {
3
- fontSizePx?: number;
4
- fontSize?: number;
5
- fontFamily?: string;
6
- bold?: boolean;
7
- italic?: boolean;
8
- underline?: boolean;
9
- color?: string;
10
- backgroundColor?: string;
11
- align?: "left" | "center" | "right" | "justify";
12
- verticalAlign?: "top" | "middle" | "bottom";
13
- lineColor?: string;
14
- borderColor?: string;
15
- lineWidthPt?: number;
16
- borderTop?: boolean;
17
- borderRight?: boolean;
18
- borderBottom?: boolean;
19
- borderLeft?: boolean;
20
- lineHeight?: number;
21
- letterSpacing?: number;
22
- opacity?: number;
23
- rotateDeg?: number;
24
- }
25
- export interface RichParagraph {
26
- segments: RichSegment[];
27
- align?: ComponentStyle["align"];
28
- lineHeight?: number;
29
- spaceBeforeMm?: number;
30
- spaceAfterMm?: number;
31
- indentMm?: number;
32
- }
33
- export interface RichSegment {
34
- kind?: "text" | "field";
35
- text?: string;
36
- field?: string;
37
- style?: ComponentStyle;
38
- }
39
- export interface GridCell {
40
- text?: string;
41
- rawText?: string;
42
- children?: PlanComponent[];
43
- colSpan?: number;
44
- rowSpan?: number;
45
- style?: ComponentStyle;
46
- }
47
- export interface PlanGrid {
48
- /** 行内允许 null 空位;渲染器按空单元格处理 */
49
- cells: (GridCell | null)[][];
50
- colWidthsMm?: number[];
51
- rowHeightsMm?: number[];
52
- gapMm?: number;
53
- }
54
- export interface PlanComponent {
55
- kind: ComponentKind;
56
- leftMm: number;
57
- topMm: number;
58
- widthMm: number;
59
- heightMm: number;
60
- nid?: string;
61
- rkey?: string;
62
- text?: string;
63
- rawText?: string;
64
- lines?: string[];
65
- richParagraphs?: RichParagraph[];
66
- imageData?: string;
67
- grid?: PlanGrid;
68
- style?: ComponentStyle;
69
- meta?: Record<string, unknown>;
70
- /** MachReport 扩展字段:未知 kind 的兜底渲染标记 */
71
- fallbackText?: string;
72
- }
73
- export interface PlanPage {
74
- pageWidthMm: number;
75
- pageHeightMm: number;
76
- marginTopMm?: number;
77
- marginBottomMm?: number;
78
- marginLeftMm?: number;
79
- marginRightMm?: number;
80
- components: PlanComponent[];
81
- }
82
- export interface RenderPlan {
83
- schemaVersion: string;
84
- pages: PlanPage[];
85
- }
86
- export declare const RENDER_PLAN_SCHEMA_VERSION = "1.0.0-mach";
87
- export declare function isImageBackedComponent(comp: PlanComponent): boolean;
88
- export declare function isRichText(comp: PlanComponent): boolean;
@@ -1,15 +0,0 @@
1
- import { PlanComponent, PlanPage } from './render-plan';
2
- export interface ValidationError {
3
- path: string;
4
- message: string;
5
- }
6
- export interface ValidationResult {
7
- ok: boolean;
8
- errors: ValidationError[];
9
- warnings: ValidationError[];
10
- }
11
- export declare function validateComponent(comp: unknown, path: string, errors: ValidationError[], warnings?: ValidationError[]): void;
12
- export declare function validatePage(page: unknown, path: string, errors: ValidationError[], warnings?: ValidationError[]): void;
13
- export declare function validateRenderPlan(input: unknown): ValidationResult;
14
- export declare function assertRenderPlan(input: unknown): PlanPage[];
15
- export type { PlanComponent, PlanPage };
@@ -1,14 +0,0 @@
1
- export interface AstCheckResult {
2
- ok: boolean;
3
- /** ast 深度校验是否执行(方言不支持时降级词法) */
4
- degraded: boolean;
5
- message?: string;
6
- }
7
- /**
8
- * AST 深度校验(双保险策略):
9
- * 1. node-sql-parser(MySQL 方言,支持 ? 占位符)AST 顶层必须为 SELECT/集合运算
10
- * 2. AST 通过后再叠加词法校验(MySQL 方言把 SELECT INTO 解析为别名,AST 层不可见,
11
- * 由词法层兜底拦截)
12
- * AST 解析失败(方言不兼容)自动降级为纯词法校验,返回 degraded=true。
13
- */
14
- export declare function assertSingleSelectAst(sql: string): AstCheckResult;