@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/pdf.d.cts CHANGED
@@ -32,6 +32,10 @@ export declare interface FontLoadOptions {
32
32
  declare interface GridCell {
33
33
  text?: string;
34
34
  rawText?: string;
35
+ /** 原始值,仅供 Excel raw 模式消费;不参与预览、分页与 PDF 绘制。 */
36
+ value?: string | number | boolean | null;
37
+ /** Excel 数字格式(例如 #,##0.00 / 0.00%),不改变 text。 */
38
+ numberFormat?: string;
35
39
  children?: PlanComponent[];
36
40
  colSpan?: number;
37
41
  rowSpan?: number;
@@ -87,6 +91,7 @@ declare interface PlanComponent {
87
91
  richParagraphs?: RichParagraph[];
88
92
  imageData?: string;
89
93
  grid?: PlanGrid;
94
+ table?: PlanTableFragment;
90
95
  style?: ComponentStyle;
91
96
  meta?: Record<string, unknown>;
92
97
  /** MachReport 扩展字段:未知 kind 的兜底渲染标记 */
@@ -102,6 +107,8 @@ declare interface PlanGrid {
102
107
  }
103
108
 
104
109
  declare interface PlanPage {
110
+ /** wide 表示完整自然列宽;页面仅为预览的垂直窗口分段。 */
111
+ layout?: "page" | "wide";
105
112
  pageWidthMm: number;
106
113
  pageHeightMm: number;
107
114
  marginTopMm?: number;
@@ -111,6 +118,19 @@ declare interface PlanPage {
111
118
  components: PlanComponent[];
112
119
  }
113
120
 
121
+ /** 列表的逻辑行来源;用于连续 Excel 重组,避免按文本猜测重复表头。 */
122
+ declare interface PlanTableFragment {
123
+ /** 在整个计划中唯一的逻辑表身份;同一表的分页片段共享身份。 */
124
+ id: string;
125
+ /** 表头固定 -1;其余行(包括组头/小计/总计)从 0 连续递增。 */
126
+ rowIndex: number;
127
+ role: "header" | "body" | "group-header" | "subtotal" | "grand-total";
128
+ /** 按物理列顺序保存字段身份;不以表头显示文本判断列结构。 */
129
+ columnKeys: string[];
130
+ layout?: "page" | "wide";
131
+ title?: string;
132
+ }
133
+
114
134
  declare interface RenderPlan {
115
135
  schemaVersion: string;
116
136
  pages: PlanPage[];
package/dist/pdf.d.ts CHANGED
@@ -32,6 +32,10 @@ export declare interface FontLoadOptions {
32
32
  declare interface GridCell {
33
33
  text?: string;
34
34
  rawText?: string;
35
+ /** 原始值,仅供 Excel raw 模式消费;不参与预览、分页与 PDF 绘制。 */
36
+ value?: string | number | boolean | null;
37
+ /** Excel 数字格式(例如 #,##0.00 / 0.00%),不改变 text。 */
38
+ numberFormat?: string;
35
39
  children?: PlanComponent[];
36
40
  colSpan?: number;
37
41
  rowSpan?: number;
@@ -87,6 +91,7 @@ declare interface PlanComponent {
87
91
  richParagraphs?: RichParagraph[];
88
92
  imageData?: string;
89
93
  grid?: PlanGrid;
94
+ table?: PlanTableFragment;
90
95
  style?: ComponentStyle;
91
96
  meta?: Record<string, unknown>;
92
97
  /** MachReport 扩展字段:未知 kind 的兜底渲染标记 */
@@ -102,6 +107,8 @@ declare interface PlanGrid {
102
107
  }
103
108
 
104
109
  declare interface PlanPage {
110
+ /** wide 表示完整自然列宽;页面仅为预览的垂直窗口分段。 */
111
+ layout?: "page" | "wide";
105
112
  pageWidthMm: number;
106
113
  pageHeightMm: number;
107
114
  marginTopMm?: number;
@@ -111,6 +118,19 @@ declare interface PlanPage {
111
118
  components: PlanComponent[];
112
119
  }
113
120
 
121
+ /** 列表的逻辑行来源;用于连续 Excel 重组,避免按文本猜测重复表头。 */
122
+ declare interface PlanTableFragment {
123
+ /** 在整个计划中唯一的逻辑表身份;同一表的分页片段共享身份。 */
124
+ id: string;
125
+ /** 表头固定 -1;其余行(包括组头/小计/总计)从 0 连续递增。 */
126
+ rowIndex: number;
127
+ role: "header" | "body" | "group-header" | "subtotal" | "grand-total";
128
+ /** 按物理列顺序保存字段身份;不以表头显示文本判断列结构。 */
129
+ columnKeys: string[];
130
+ layout?: "page" | "wide";
131
+ title?: string;
132
+ }
133
+
114
134
  declare interface RenderPlan {
115
135
  schemaVersion: string;
116
136
  pages: PlanPage[];
package/dist/pdf.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { g as W1 } from "./_commonjsHelpers-DaMA6jEr.js";
2
- import { h as G1, i as H1, c as So, d as yl, b as ml, L as yu, a as Rd, w as K1 } from "./style-DnmtG7Gl.js";
3
- import { r as X1 } from "./grid-geometry-Bs8QXz1X.js";
2
+ import { c as So, d as yl, g as G1, L as yu, r as Rd } from "./grid-geometry-CWmJ9c9y.js";
3
+ import { h as H1, i as K1, a as ml, w as X1 } from "./textwrap-BQyrpYSR.js";
4
4
  var mu = {}, bl;
5
5
  function Kn() {
6
6
  return bl || (bl = 1, (function(t) {
@@ -35939,11 +35939,11 @@ async function VE(t, e = {}) {
35939
35939
  r.registerFontkit(Zn);
35940
35940
  const n = [], i = [];
35941
35941
  let a = 0;
35942
- const o = e.measurer ?? G1, s = await r.embedFont(ao.Helvetica), f = (e.customFontBytes ? await r.embedFont(e.customFontBytes, {
35942
+ const o = e.measurer ?? H1, s = await r.embedFont(ao.Helvetica), f = (e.customFontBytes ? await r.embedFont(e.customFontBytes, {
35943
35943
  subset: !0
35944
35944
  }) : void 0) ?? s, l = /* @__PURE__ */ new Map();
35945
35945
  function h(w, x, T) {
35946
- return w ? K1(w, x, { fontSizePt: T }, o) : [];
35946
+ return w ? X1(w, x, { fontSizePt: T }, o) : [];
35947
35947
  }
35948
35948
  function d(w) {
35949
35949
  const x = l.get(w);
@@ -35977,7 +35977,7 @@ async function VE(t, e = {}) {
35977
35977
  });
35978
35978
  }
35979
35979
  function g(w, x, T, A, R) {
35980
- const P = X1(x, T.widthMm, T.heightMm), I = yl(T.style), B = So(T.style), j = oi(B.color, [0.2, 0.2, 0.2]), W = Math.max(0.1, B.widthPt);
35980
+ const P = G1(x, T.widthMm, T.heightMm), I = yl(T.style), B = So(T.style), j = oi(B.color, [0.2, 0.2, 0.2]), W = Math.max(0.1, B.widthPt);
35981
35981
  for (const N of P.cells) {
35982
35982
  const V = N.cell.style?.backgroundColor;
35983
35983
  V && w.drawRectangle({
@@ -36029,7 +36029,7 @@ async function VE(t, e = {}) {
36029
36029
  for (const P of x.components) {
36030
36030
  const I = At(P.leftMm), B = A - At(P.topMm), j = At(P.widthMm), W = At(P.heightMm);
36031
36031
  try {
36032
- if (H1(P)) {
36032
+ if (K1(P)) {
36033
36033
  const N = await d(P.imageData);
36034
36034
  N ? R.drawImage(N, { x: I, y: B - W, width: j, height: W }) : i.push(
36035
36035
  `page ${w + 1} ${P.nid ?? P.kind}: 图片仅支持 data:image/(png|jpeg) base64,已跳过`
@@ -1 +1 @@
1
- "use strict";var l=Object.create;var n=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty;var m=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let c of p(e))!h.call(r,c)&&c!==t&&n(r,c,{get:()=>e[c],enumerable:!(o=s(e,c))||o.enumerable});return r};var C=(r,e,t)=>(t=r!=null?l(d(r)):{},m(e||!r||!r.__esModule?n(t,"default",{value:r,enumerable:!0}):t,r));const E=require("vue"),O=require("./report-params-D1NeY-eR.cjs"),_="mach-report/fetcher",f="mach-report/pdf-exporter",P="mach-report/config",u="mach-report/controller",a=E.defineAsyncComponent(()=>Promise.resolve().then(()=>require("./ReportPreview-VHAIfsz1.cjs")).then(r=>r.ReportPreview$1)),T={install(r,e={}){let t=e.fetcher;if(!t&&e.reports){const o=e.reports;let c;t=async R=>(c??=import("@agile-team/mach-report").then(({createReportSource:i})=>i(o)),(await c)(R)),t.getParamDefs=R=>O.getReportParamDefs(o,R)}t&&r.provide(_,t),e.pdfExporter&&r.provide(f,e.pdfExporter),r.provide(P,E.computed(()=>{if(e.pdfFontUrl===void 0)return e.config??null;const o=e.config??{defaults:{},presets:{}};return{...o,defaults:{...o.defaults,pdfFontUrl:e.pdfFontUrl}}})),e.globalComponent!==!1&&!r.component("MachReportPreview")&&r.component("MachReportPreview",a)}};exports.MACH_REPORT_CONFIG_KEY=P;exports.MACH_REPORT_CONTROLLER_KEY=u;exports.MACH_REPORT_FETCHER_KEY=_;exports.MACH_REPORT_PDF_EXPORTER_KEY=f;exports.MachReportPreview=a;exports.machReportPlugin=T;
1
+ "use strict";var l=Object.create;var n=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty;var m=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let c of p(e))!h.call(r,c)&&c!==t&&n(r,c,{get:()=>e[c],enumerable:!(o=s(e,c))||o.enumerable});return r};var C=(r,e,t)=>(t=r!=null?l(d(r)):{},m(e||!r||!r.__esModule?n(t,"default",{value:r,enumerable:!0}):t,r));const E=require("vue"),O=require("./report-params-D1gZ1DME.cjs"),_="mach-report/fetcher",f="mach-report/pdf-exporter",P="mach-report/config",u="mach-report/controller",a=E.defineAsyncComponent(()=>Promise.resolve().then(()=>require("./ReportPreview-CLENbOCL.cjs")).then(r=>r.ReportPreview$1)),T={install(r,e={}){let t=e.fetcher;if(!t&&e.reports){const o=e.reports;let c;t=async R=>(c??=import("@agile-team/mach-report").then(({createReportSource:i})=>i(o)),(await c)(R)),t.getParamDefs=R=>O.getReportParamDefs(o,R)}t&&r.provide(_,t),e.pdfExporter&&r.provide(f,e.pdfExporter),r.provide(P,E.computed(()=>{if(e.pdfFontUrl===void 0)return e.config??null;const o=e.config??{defaults:{},presets:{}};return{...o,defaults:{...o.defaults,pdfFontUrl:e.pdfFontUrl}}})),e.globalComponent!==!1&&!r.component("MachReportPreview")&&r.component("MachReportPreview",a)}};exports.MACH_REPORT_CONFIG_KEY=P;exports.MACH_REPORT_CONTROLLER_KEY=u;exports.MACH_REPORT_FETCHER_KEY=_;exports.MACH_REPORT_PDF_EXPORTER_KEY=f;exports.MachReportPreview=a;exports.machReportPlugin=T;
@@ -1,6 +1,6 @@
1
1
  import { defineAsyncComponent as a, computed as s } from "vue";
2
- import { g as m } from "./report-params-BB85g7mg.js";
3
- const p = "mach-report/fetcher", l = "mach-report/pdf-exporter", R = "mach-report/config", h = "mach-report/controller", d = a(() => import("./ReportPreview-Dwdsyk9b.js").then((r) => r.s)), _ = {
2
+ import { g as m } from "./report-params-B3Fia6JO.js";
3
+ const p = "mach-report/fetcher", l = "mach-report/pdf-exporter", R = "mach-report/config", h = "mach-report/controller", d = a(() => import("./ReportPreview-CwTGfyTq.js").then((r) => r.s)), _ = {
4
4
  install(r, e = {}) {
5
5
  let t = e.fetcher;
6
6
  if (!t && e.reports) {
@@ -0,0 +1,10 @@
1
+ function s(e, f) {
2
+ const a = /* @__PURE__ */ new Set();
3
+ return f.flatMap((r) => {
4
+ const t = Object.prototype.hasOwnProperty.call(e, r) ? e[r] : void 0;
5
+ return (t?.params ?? (typeof t?.template == "function" ? [] : t?.template.params) ?? []).filter((n) => a.has(n.field) ? !1 : (a.add(n.field), !0));
6
+ });
7
+ }
8
+ export {
9
+ s as g
10
+ };
@@ -0,0 +1 @@
1
+ "use strict";function f(e,s){const a=new Set;return s.flatMap(r=>{const t=Object.prototype.hasOwnProperty.call(e,r)?e[r]:void 0;return(t?.params??(typeof t?.template=="function"?[]:t?.template.params)??[]).filter(n=>a.has(n.field)?!1:(a.add(n.field),!0))})}exports.getReportParamDefs=f;
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .mrp-toolbar[data-v-48cc0980]{display:flex;align-items:center;gap:8px;padding:6px 12px;background:var(--mrp-toolbar-bg, #323639);border-bottom:1px solid var(--mrp-toolbar-border, #22252a);flex:none;flex-wrap:wrap}.mrp-title[data-v-48cc0980]{font-size:13px;font-weight:600;margin-right:8px;color:var(--mrp-toolbar-fg, #e8e8e8)}.mrp-nav[data-v-48cc0980]{background:transparent;color:var(--mrp-btn-fg, #cfcfcf);border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:2px 8px;font-size:12px;cursor:pointer;white-space:nowrap}.mrp-nav[data-v-48cc0980]:hover:not(:disabled){background:var(--mrp-btn-hover-bg, #414549);color:var(--mrp-btn-hover-fg, #fff)}.mrp-nav[data-v-48cc0980]:disabled{opacity:.4;cursor:not-allowed}.mrp-active[data-v-48cc0980]{background:var(--mrp-btn-active-bg, #2d5fb8);border-color:var(--mrp-btn-active-bg, #2d5fb8);color:#fff}.mrp-pageinfo[data-v-48cc0980]{font-size:12px;min-width:56px;text-align:center;color:var(--mrp-toolbar-fg, #e8e8e8)}.mrp-spacer[data-v-48cc0980]{flex:1}.mrp-search[data-v-48cc0980]{display:flex;align-items:center;gap:4px}.mrp-search-input[data-v-48cc0980]{background:#22252a;color:#e8e8e8;border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:2px 8px;font-size:12px;width:150px;outline:none}.mrp-search-input[data-v-48cc0980]:focus{border-color:var(--mrp-btn-active-bg, #2d5fb8)}.mrp-search-count[data-v-48cc0980]{font-size:12px;color:var(--mrp-toolbar-fg, #e8e8e8);min-width:42px;text-align:center}.mrp-params[data-v-aafce92d]{display:flex;align-items:flex-end;gap:12px;padding:6px 12px;background:var(--mrp-toolbar-bg, #323639);border-bottom:1px solid var(--mrp-toolbar-border, #22252a);flex:none;flex-wrap:wrap}.mrp-params-title[data-v-aafce92d]{font-size:12px;font-weight:600;color:var(--mrp-toolbar-fg, #e8e8e8);padding-bottom:5px;white-space:nowrap}.mrp-params-grid[data-v-aafce92d]{display:flex;flex-wrap:wrap;gap:8px 12px;flex:1}.mrp-param[data-v-aafce92d]{display:flex;flex-direction:column;gap:2px}.mrp-param-label[data-v-aafce92d]{font-size:11px;color:var(--mrp-toolbar-fg, #e8e8e8);opacity:.85}.mrp-param-star[data-v-aafce92d]{color:#ff7b72;font-style:normal;margin-left:2px}.mrp-param-input[data-v-aafce92d]{background:#22252a;color:#e8e8e8;border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:3px 8px;font-size:12px;min-width:130px;outline:none}.mrp-param-input[data-v-aafce92d]:focus{border-color:var(--mrp-btn-active-bg, #2d5fb8)}.mrp-param-missing .mrp-param-input[data-v-aafce92d]{border-color:#ff7b72}select.mrp-param-input option[data-v-aafce92d]{background:#22252a}.mrp-params-actions[data-v-aafce92d]{display:flex;gap:6px;padding-bottom:1px}.mrp-nav[data-v-aafce92d]{background:transparent;color:var(--mrp-btn-fg, #cfcfcf);border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:4px 14px;font-size:12px;cursor:pointer;white-space:nowrap}.mrp-nav[data-v-aafce92d]:hover{background:var(--mrp-btn-hover-bg, #414549);color:var(--mrp-btn-hover-fg, #fff)}.mrp-param-query[data-v-aafce92d]{background:var(--mrp-btn-active-bg, #2d5fb8);border-color:var(--mrp-btn-active-bg, #2d5fb8);color:#fff}.mach-report-preview[data-v-28af6d98]{--mrp-shell-bg: #525659;--mrp-shell-fg: #e8e8e8;--mrp-toolbar-bg: #323639;--mrp-toolbar-border: #22252a;--mrp-toolbar-fg: #e8e8e8;--mrp-btn-fg: #cfcfcf;--mrp-btn-border: #4a4d52;--mrp-btn-hover-bg: #414549;--mrp-btn-hover-fg: #ffffff;--mrp-btn-active-bg: #2d5fb8;position:relative;display:flex;flex-direction:column;background:var(--mrp-shell-bg);color:var(--mrp-shell-fg);overflow:hidden}.mrp-main[data-v-28af6d98]{display:flex;flex:1;min-height:0}.mrp-body[data-v-28af6d98]{flex:1;overflow:auto;padding:24px;outline:none}.mrp-scale[data-v-28af6d98]{margin:0 auto}.mrp-scale-inner[data-v-28af6d98]{display:flex;flex-direction:column;align-items:center}.mrp-page-holder[data-v-28af6d98]{background:#fff;box-shadow:0 2px 8px #00000059;margin-bottom:var(--v45530c0c);flex:none}.mrp-state[data-v-28af6d98]{padding:40px;text-align:center;color:#bfbfbf;font-size:13px}.mrp-error[data-v-28af6d98]{color:#ff9d9d}.mrp-export-notice[data-v-28af6d98]{padding:7px 12px;font-size:12px;background:#fff0c2;color:#613c00}.mrp-export-error[data-v-28af6d98]{background:#ffe0df;color:#8e1f1f}.mrp-export-progress[data-v-28af6d98]{background:#e7f0ff;color:#1a4d86}.mrp-retry[data-v-28af6d98]{margin-left:12px;background:transparent;color:#8fb7ff;border:1px solid #5a7fbf;border-radius:4px;padding:1px 10px;cursor:pointer}.mrp-overlay[data-v-28af6d98]{position:absolute;inset:0;pointer-events:none}.mrp-page-holder[data-v-28af6d98] mark.mrp-hit{background:#ffe066;color:#7a5c00;border-radius:2px;padding:0 1px}.mrp-thumbs[data-v-28af6d98]{width:140px;flex:none;overflow-y:auto;border-left:1px solid var(--mrp-toolbar-border);background:var(--mrp-toolbar-bg);padding:8px;display:flex;flex-direction:column;gap:8px}.mrp-thumb[data-v-28af6d98]{cursor:pointer;text-align:center}.mrp-thumb-box[data-v-28af6d98]{width:116px;background:#fff;box-shadow:0 1px 4px #0006;overflow:hidden;border:2px solid transparent}.mrp-thumb-active .mrp-thumb-box[data-v-28af6d98]{border-color:var(--mrp-btn-active-bg)}.mrp-thumb-no[data-v-28af6d98]{font-size:11px;color:var(--mrp-toolbar-fg)}.mrp-debug[data-v-28af6d98]{position:absolute;right:8px;bottom:8px;background:#000000c7;color:#7ee787;font:11px/1.6 ui-monospace,monospace;padding:6px 10px;border-radius:6px;pointer-events:none;white-space:pre}
1
+ .mrp-toolbar[data-v-601f8fa8]{display:flex;align-items:center;gap:8px;padding:6px 12px;background:var(--mrp-toolbar-bg, #323639);border-bottom:1px solid var(--mrp-toolbar-border, #22252a);flex:none;flex-wrap:wrap}.mrp-title[data-v-601f8fa8]{font-size:13px;font-weight:600;margin-right:8px;color:var(--mrp-toolbar-fg, #e8e8e8)}.mrp-nav[data-v-601f8fa8]{background:transparent;color:var(--mrp-btn-fg, #cfcfcf);border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:2px 8px;font-size:12px;cursor:pointer;white-space:nowrap}.mrp-nav[data-v-601f8fa8]:hover:not(:disabled){background:var(--mrp-btn-hover-bg, #414549);color:var(--mrp-btn-hover-fg, #fff)}.mrp-nav[data-v-601f8fa8]:disabled{opacity:.4;cursor:not-allowed}.mrp-active[data-v-601f8fa8]{background:var(--mrp-btn-active-bg, #2d5fb8);border-color:var(--mrp-btn-active-bg, #2d5fb8);color:#fff}.mrp-pageinfo[data-v-601f8fa8]{font-size:12px;min-width:56px;text-align:center;color:var(--mrp-toolbar-fg, #e8e8e8)}.mrp-spacer[data-v-601f8fa8]{flex:1}.mrp-search[data-v-601f8fa8]{display:flex;align-items:center;gap:4px}.mrp-search-input[data-v-601f8fa8]{background:#22252a;color:#e8e8e8;border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:2px 8px;font-size:12px;width:150px;outline:none}.mrp-search-input[data-v-601f8fa8]:focus{border-color:var(--mrp-btn-active-bg, #2d5fb8)}.mrp-search-count[data-v-601f8fa8]{font-size:12px;color:var(--mrp-toolbar-fg, #e8e8e8);min-width:42px;text-align:center}.mrp-params[data-v-aafce92d]{display:flex;align-items:flex-end;gap:12px;padding:6px 12px;background:var(--mrp-toolbar-bg, #323639);border-bottom:1px solid var(--mrp-toolbar-border, #22252a);flex:none;flex-wrap:wrap}.mrp-params-title[data-v-aafce92d]{font-size:12px;font-weight:600;color:var(--mrp-toolbar-fg, #e8e8e8);padding-bottom:5px;white-space:nowrap}.mrp-params-grid[data-v-aafce92d]{display:flex;flex-wrap:wrap;gap:8px 12px;flex:1}.mrp-param[data-v-aafce92d]{display:flex;flex-direction:column;gap:2px}.mrp-param-label[data-v-aafce92d]{font-size:11px;color:var(--mrp-toolbar-fg, #e8e8e8);opacity:.85}.mrp-param-star[data-v-aafce92d]{color:#ff7b72;font-style:normal;margin-left:2px}.mrp-param-input[data-v-aafce92d]{background:#22252a;color:#e8e8e8;border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:3px 8px;font-size:12px;min-width:130px;outline:none}.mrp-param-input[data-v-aafce92d]:focus{border-color:var(--mrp-btn-active-bg, #2d5fb8)}.mrp-param-missing .mrp-param-input[data-v-aafce92d]{border-color:#ff7b72}select.mrp-param-input option[data-v-aafce92d]{background:#22252a}.mrp-params-actions[data-v-aafce92d]{display:flex;gap:6px;padding-bottom:1px}.mrp-nav[data-v-aafce92d]{background:transparent;color:var(--mrp-btn-fg, #cfcfcf);border:1px solid var(--mrp-btn-border, #4a4d52);border-radius:4px;padding:4px 14px;font-size:12px;cursor:pointer;white-space:nowrap}.mrp-nav[data-v-aafce92d]:hover{background:var(--mrp-btn-hover-bg, #414549);color:var(--mrp-btn-hover-fg, #fff)}.mrp-param-query[data-v-aafce92d]{background:var(--mrp-btn-active-bg, #2d5fb8);border-color:var(--mrp-btn-active-bg, #2d5fb8);color:#fff}.mach-report-preview[data-v-449298a6]{--mrp-shell-bg: #525659;--mrp-shell-fg: #e8e8e8;--mrp-toolbar-bg: #323639;--mrp-toolbar-border: #22252a;--mrp-toolbar-fg: #e8e8e8;--mrp-btn-fg: #cfcfcf;--mrp-btn-border: #4a4d52;--mrp-btn-hover-bg: #414549;--mrp-btn-hover-fg: #ffffff;--mrp-btn-active-bg: #2d5fb8;position:relative;display:flex;flex-direction:column;background:var(--mrp-shell-bg);color:var(--mrp-shell-fg);overflow:hidden}.mrp-main[data-v-449298a6]{display:flex;flex:1;min-height:0}.mrp-body[data-v-449298a6]{flex:1;min-width:0;overflow:auto;padding:24px;outline:none}.mrp-scale[data-v-449298a6]{position:relative;margin:0 auto}.mrp-scale-inner[data-v-449298a6]{position:absolute;left:0;top:0;display:flex;flex-direction:column;align-items:center}.mrp-page-holder[data-v-449298a6]{background:#fff;box-shadow:0 2px 8px #00000059;margin-bottom:var(--v5d32312f);flex:none}.mrp-wide-report .mrp-page-holder[data-v-449298a6]{box-shadow:none}.mrp-state[data-v-449298a6]{padding:40px;text-align:center;color:#bfbfbf;font-size:13px}.mrp-error[data-v-449298a6]{color:#ff9d9d}.mrp-export-notice[data-v-449298a6]{padding:7px 12px;font-size:12px;background:#fff0c2;color:#613c00}.mrp-export-error[data-v-449298a6]{background:#ffe0df;color:#8e1f1f}.mrp-export-progress[data-v-449298a6]{background:#e7f0ff;color:#1a4d86}.mrp-retry[data-v-449298a6]{margin-left:12px;background:transparent;color:#8fb7ff;border:1px solid #5a7fbf;border-radius:4px;padding:1px 10px;cursor:pointer}.mrp-overlay[data-v-449298a6]{position:absolute;inset:0;pointer-events:none}.mrp-page-holder[data-v-449298a6] mark.mrp-hit{background:#ffe066;color:#7a5c00;border-radius:2px;padding:0 1px;scroll-margin:8px}.mrp-thumbs[data-v-449298a6]{width:140px;flex:none;overflow-y:auto;border-left:1px solid var(--mrp-toolbar-border);background:var(--mrp-toolbar-bg);padding:8px;display:flex;flex-direction:column}.mrp-thumb[data-v-449298a6]{cursor:pointer;text-align:center;flex:none;margin-bottom:8px}.mrp-thumb-spacer[data-v-449298a6]{flex:none}.mrp-thumb-box[data-v-449298a6]{box-sizing:border-box;width:116px;background:#fff;box-shadow:0 1px 4px #0006;overflow:hidden;border:2px solid transparent}.mrp-thumb-active .mrp-thumb-box[data-v-449298a6]{border-color:var(--mrp-btn-active-bg)}.mrp-thumb-no[data-v-449298a6]{display:block;margin-top:4px;line-height:16px;font-size:11px;color:var(--mrp-toolbar-fg)}.mrp-debug[data-v-449298a6]{position:absolute;right:8px;bottom:8px;background:#000000c7;color:#7ee787;font:11px/1.6 ui-monospace,monospace;padding:6px 10px;border-radius:6px;pointer-events:none;white-space:pre}
@@ -0,0 +1,117 @@
1
+ import { S as l } from "./grid-geometry-CWmJ9c9y.js";
2
+ const x = l;
3
+ function g(t) {
4
+ return (t.kind === "image" || t.kind === "barcode" || t.kind === "qrcode" || t.kind === "chart") && !!t.imageData;
5
+ }
6
+ function C(t) {
7
+ return t.kind === "text" && Array.isArray(t.richParagraphs) && t.richParagraphs.length > 0;
8
+ }
9
+ const m = /[\u3000-\u9fff\uff00-\uffef]/, o = new Uint8Array(128);
10
+ {
11
+ for (const t of "iljtf.,:;'`|!()[]") o[t.charCodeAt(0)] = 1;
12
+ for (const t of "mwMW@") o[t.charCodeAt(0)] = 2;
13
+ for (let t = 48; t <= 57; t++) o[t] = 3;
14
+ for (let t = 65; t <= 90; t++) o[t] = 4;
15
+ o[32] = 5;
16
+ }
17
+ const M = [0.54, 0.26, 0.95, 0.59, 0.67, 0.3];
18
+ function w(t) {
19
+ const e = t.charCodeAt(0);
20
+ return e < 128 ? M[o[e]] : m.test(t) ? 1 : /[A-Z]/.test(t) ? 0.67 : 0.54;
21
+ }
22
+ const a = {
23
+ measureMm(t, e) {
24
+ const { fontSizePt: f, bold: s = !1, letterSpacingPt: u = 0 } = e, i = 25.4 / 72;
25
+ let r = 0;
26
+ for (const n of t)
27
+ r += w(n);
28
+ return s && (r *= 1.04), (r * f + u * t.length) * i;
29
+ }
30
+ };
31
+ function S() {
32
+ return a;
33
+ }
34
+ function E(t, e) {
35
+ return a.measureMm(t, e);
36
+ }
37
+ function T(t) {
38
+ let e;
39
+ return {
40
+ measureMm(f, s) {
41
+ if (e === void 0 && (e = t()), !e) return a.measureMm(f, s);
42
+ const u = s.fontSizePt * 96 / 72;
43
+ return e.font = `${s.bold ? "bold " : ""}${u}px sans-serif`, e.measureText(f).width * 25.4 / 96;
44
+ }
45
+ };
46
+ }
47
+ function A(t, e, f) {
48
+ const s = [];
49
+ let u = "", i = 0;
50
+ const r = () => {
51
+ u && (s.push({ text: u, widthMm: i, cjk: !1 }), u = "", i = 0);
52
+ };
53
+ for (const n of t) {
54
+ if (n === `
55
+ `) {
56
+ r(), s.push({ text: `
57
+ `, widthMm: 0, cjk: !1, br: !0 });
58
+ continue;
59
+ }
60
+ if (n === " ") {
61
+ r(), s.push({ text: n, widthMm: f.measureMm(n, e), cjk: !1, space: !0 });
62
+ continue;
63
+ }
64
+ if (m.test(n)) {
65
+ r(), s.push({ text: n, widthMm: f.measureMm(n, e), cjk: !0 });
66
+ continue;
67
+ }
68
+ u += n, i += f.measureMm(n, e);
69
+ }
70
+ return r(), s;
71
+ }
72
+ function _(t, e, f, s = a) {
73
+ if (!t) return [""];
74
+ const u = [];
75
+ let i = "", r = 0;
76
+ const n = () => {
77
+ u.push(i), i = "", r = 0;
78
+ };
79
+ for (const c of A(t, f, s)) {
80
+ if (c.br) {
81
+ n();
82
+ continue;
83
+ }
84
+ if (r + c.widthMm <= e) {
85
+ i += c.text, r += c.widthMm;
86
+ continue;
87
+ }
88
+ if (c.space) {
89
+ n();
90
+ continue;
91
+ }
92
+ if (c.cjk) {
93
+ i.length > 0 && n(), i = c.text, r = c.widthMm;
94
+ continue;
95
+ }
96
+ if (i.length > 0 && n(), c.widthMm <= e) {
97
+ i = c.text, r = c.widthMm;
98
+ continue;
99
+ }
100
+ for (const h of c.text) {
101
+ const d = s.measureMm(h, f);
102
+ r + d > e && i.length > 0 && n(), i += h, r += d;
103
+ }
104
+ }
105
+ return n(), u;
106
+ }
107
+ export {
108
+ x as R,
109
+ C as a,
110
+ T as b,
111
+ w as c,
112
+ S as d,
113
+ a as h,
114
+ g as i,
115
+ E as m,
116
+ _ as w
117
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";const l=require("./grid-geometry-DBH9ExuY.cjs"),w=l.SCHEMA_VERSION_MACH;function A(t){return(t.kind==="image"||t.kind==="barcode"||t.kind==="qrcode"||t.kind==="chart")&&!!t.imageData}function x(t){return t.kind==="text"&&Array.isArray(t.richParagraphs)&&t.richParagraphs.length>0}const m=/[\u3000-\u9fff\uff00-\uffef]/,o=new Uint8Array(128);{for(const t of"iljtf.,:;'`|!()[]")o[t.charCodeAt(0)]=1;for(const t of"mwMW@")o[t.charCodeAt(0)]=2;for(let t=48;t<=57;t++)o[t]=3;for(let t=65;t<=90;t++)o[t]=4;o[32]=5}const g=[.54,.26,.95,.59,.67,.3];function M(t){const e=t.charCodeAt(0);return e<128?g[o[e]]:m.test(t)?1:/[A-Z]/.test(t)?.67:.54}const a={measureMm(t,e){const{fontSizePt:s,bold:c=!1,letterSpacingPt:f=0}=e,i=25.4/72;let n=0;for(const r of t)n+=M(r);return c&&(n*=1.04),(n*s+f*t.length)*i}};function k(){return a}function C(t,e){return a.measureMm(t,e)}function E(t){let e;return{measureMm(s,c){if(e===void 0&&(e=t()),!e)return a.measureMm(s,c);const f=c.fontSizePt*96/72;return e.font=`${c.bold?"bold ":""}${f}px sans-serif`,e.measureText(s).width*25.4/96}}}function S(t,e,s){const c=[];let f="",i=0;const n=()=>{f&&(c.push({text:f,widthMm:i,cjk:!1}),f="",i=0)};for(const r of t){if(r===`
2
+ `){n(),c.push({text:`
3
+ `,widthMm:0,cjk:!1,br:!0});continue}if(r===" "){n(),c.push({text:r,widthMm:s.measureMm(r,e),cjk:!1,space:!0});continue}if(m.test(r)){n(),c.push({text:r,widthMm:s.measureMm(r,e),cjk:!0});continue}f+=r,i+=s.measureMm(r,e)}return n(),c}function T(t,e,s,c=a){if(!t)return[""];const f=[];let i="",n=0;const r=()=>{f.push(i),i="",n=0};for(const u of S(t,s,c)){if(u.br){r();continue}if(n+u.widthMm<=e){i+=u.text,n+=u.widthMm;continue}if(u.space){r();continue}if(u.cjk){i.length>0&&r(),i=u.text,n=u.widthMm;continue}if(i.length>0&&r(),u.widthMm<=e){i=u.text,n=u.widthMm;continue}for(const h of u.text){const d=c.measureMm(h,s);n+d>e&&i.length>0&&r(),i+=h,n+=d}}return r(),f}exports.RENDER_PLAN_SCHEMA_VERSION=w;exports.charWidthEm=M;exports.createCanvasMeasurer=E;exports.createHeuristicMeasurer=k;exports.heuristicMeasurer=a;exports.isImageBackedComponent=A;exports.isRichText=x;exports.measureTextMm=C;exports.wrapText=T;
@@ -69,17 +69,30 @@ declare type DatasetRows = Record<string, Record<string, unknown>[]>;
69
69
  declare interface GridCell {
70
70
  text?: string;
71
71
  rawText?: string;
72
+ /** 原始值,仅供 Excel raw 模式消费;不参与预览、分页与 PDF 绘制。 */
73
+ value?: string | number | boolean | null;
74
+ /** Excel 数字格式(例如 #,##0.00 / 0.00%),不改变 text。 */
75
+ numberFormat?: string;
72
76
  children?: PlanComponent[];
73
77
  colSpan?: number;
74
78
  rowSpan?: number;
75
79
  style?: ComponentStyle;
76
80
  }
77
81
 
82
+ /** auto:真实数字/显式数值格式居右,日期与布尔居中,其他内容居左。 */
83
+ declare type ListAlignment = NonNullable<ComponentStyle["align"]> | "auto";
84
+
78
85
  declare interface ListColumn {
79
86
  header: string;
80
87
  field: string;
81
88
  widthMm: number;
82
89
  style?: ComponentStyle;
90
+ /** 内容对齐,优先于 style.align;数值字符串不会自动判为数字。 */
91
+ align?: ListAlignment;
92
+ /** 独立的表头对齐,不改变内容对齐。 */
93
+ headerAlign?: ComponentStyle["align"];
94
+ /** 独立的表头样式,优先于列表级表头样式。 */
95
+ headerStyle?: ComponentStyle;
83
96
  /** 值格式化(声明式):千分位/小数位、百分比、日期 pattern */
84
97
  format?: ColumnFormat;
85
98
  /** 条件格式规则(声明式,命中合并进单元格样式;如负数红字) */
@@ -89,6 +102,10 @@ declare interface ListColumn {
89
102
  declare interface ListComponent {
90
103
  kind: "list";
91
104
  id?: string;
105
+ /** 宽表标记用于连续 Excel;不改变低层列表的列宽和分页算法。 */
106
+ layout?: "page" | "wide";
107
+ /** 逻辑表名称,供 Excel Sheet 命名;不额外生成标题组件。 */
108
+ title?: string;
92
109
  leftMm: number;
93
110
  topMm: number;
94
111
  widthMm: number;
@@ -100,6 +117,11 @@ declare interface ListComponent {
100
117
  paddingMm?: number;
101
118
  headerEveryPage?: boolean;
102
119
  headerBackgroundColor?: string;
120
+ /** 内容默认对齐,列配置可覆盖;低层模板缺省仍为 left。 */
121
+ align?: ListAlignment;
122
+ /** 表头默认对齐,列配置可覆盖。 */
123
+ headerAlign?: ComponentStyle["align"];
124
+ headerStyle?: ComponentStyle;
103
125
  border?: boolean;
104
126
  /** 分组小计(组头/组尾小计/组头防孤行) */
105
127
  groupBy?: ListGroupBy;
@@ -159,6 +181,9 @@ declare interface MachReportDefaults {
159
181
  messages?: Partial<MachReportMessages>;
160
182
  /** 校验告警等内部日志通道(默认 console;静默传 { warn: () => {}, info: () => {} }) */
161
183
  logger?: MachReportLogger;
184
+ preview?: MachReportPreviewOptions;
185
+ /** Excel 出口配置,按字段继承;不配置使用导出器默认值。 */
186
+ xlsx?: XlsxRenderOptions;
162
187
  }
163
188
 
164
189
  /**
@@ -215,6 +240,8 @@ declare interface MachReportMessages {
215
240
  reset: string;
216
241
  /** 必填缺失提示({label} 占位) */
217
242
  paramRequired: string;
243
+ /** 可选搜索进度文案,旧完整 messages 对象无需新增字段。 */
244
+ searching?: string;
218
245
  }
219
246
 
220
247
  declare interface MachReportPluginOptions {
@@ -544,6 +571,14 @@ fetcher: PlanFetcher | null;
544
571
  };
545
572
  });
546
573
 
574
+ /** 预览按需调优;默认已经启用正文/缩略图虚拟化及可取消的分片搜索。 */
575
+ declare interface MachReportPreviewOptions {
576
+ /** 视口前后额外保留的正文页数,默认 1,归一化到 0~10 的整数。 */
577
+ overscanPages?: number;
578
+ /** 搜索输入防抖毫秒,默认 200,归一化到 0~2000。 */
579
+ searchDebounceMs?: number;
580
+ }
581
+
547
582
  /** 只读快照,由组件的同一套状态驱动;无需通过事件另建状态。 */
548
583
  declare interface MachReportState {
549
584
  readonly loading: boolean;
@@ -617,6 +652,7 @@ declare interface PlanComponent {
617
652
  richParagraphs?: RichParagraph[];
618
653
  imageData?: string;
619
654
  grid?: PlanGrid;
655
+ table?: PlanTableFragment;
620
656
  style?: ComponentStyle;
621
657
  meta?: Record<string, unknown>;
622
658
  /** MachReport 扩展字段:未知 kind 的兜底渲染标记 */
@@ -637,6 +673,8 @@ declare interface PlanGrid {
637
673
  }
638
674
 
639
675
  declare interface PlanPage {
676
+ /** wide 表示完整自然列宽;页面仅为预览的垂直窗口分段。 */
677
+ layout?: "page" | "wide";
640
678
  pageWidthMm: number;
641
679
  pageHeightMm: number;
642
680
  marginTopMm?: number;
@@ -646,6 +684,19 @@ declare interface PlanPage {
646
684
  components: PlanComponent[];
647
685
  }
648
686
 
687
+ /** 列表的逻辑行来源;用于连续 Excel 重组,避免按文本猜测重复表头。 */
688
+ declare interface PlanTableFragment {
689
+ /** 在整个计划中唯一的逻辑表身份;同一表的分页片段共享身份。 */
690
+ id: string;
691
+ /** 表头固定 -1;其余行(包括组头/小计/总计)从 0 连续递增。 */
692
+ rowIndex: number;
693
+ role: "header" | "body" | "group-header" | "subtotal" | "grand-total";
694
+ /** 按物理列顺序保存字段身份;不以表头显示文本判断列结构。 */
695
+ columnKeys: string[];
696
+ layout?: "page" | "wide";
697
+ title?: string;
698
+ }
699
+
649
700
  /** 预取组件分片(路由 hover / 空闲时调用,正式渲染零等待) */
650
701
  export declare function preloadMachReport(): Promise<unknown>;
651
702
 
@@ -655,11 +706,12 @@ declare interface RenderPlan {
655
706
  }
656
707
 
657
708
  declare interface ReportDefinition {
658
- template: ReportTemplate;
709
+ /** 静态模板或宿主提供的异步模板加载器;动态模板默认每次重新读取,不缓存版本。 */
710
+ template: ReportTemplate | ReportTemplateLoader;
659
711
  /** 静态数据;load 存在时优先使用 load 的结果。 */
660
712
  datasets?: DatasetRows;
661
713
  load?: (context: ReportLoadContext) => DatasetRows | Promise<DatasetRows>;
662
- /** 覆盖模板参数定义,未提供时自动使用 template.params。 */
714
+ /** 覆盖模板参数定义;动态模板应在此声明查询面板元数据,避免查询前先请求模板。 */
663
715
  params?: ReportParamDef[];
664
716
  pagination?: PaginateOptions;
665
717
  }
@@ -708,6 +760,8 @@ declare interface ReportTemplate {
708
760
  pages: TemplatePage[];
709
761
  }
710
762
 
763
+ declare type ReportTemplateLoader = (context: ReportLoadContext) => ReportTemplate | Promise<ReportTemplate>;
764
+
711
765
  declare interface RichParagraph {
712
766
  segments: RichSegment[];
713
767
  align?: ComponentStyle["align"];
@@ -740,6 +794,8 @@ declare type TemplateComponent = PlanComponent | ListComponent;
740
794
  declare interface TemplatePage {
741
795
  widthMm: number;
742
796
  heightMm: number;
797
+ /** 宽表保持全列自然宽度,页高只控制内部纵向分段。 */
798
+ layout?: "page" | "wide";
743
799
  marginTopMm?: number;
744
800
  marginBottomMm?: number;
745
801
  marginLeftMm?: number;
@@ -766,4 +822,23 @@ declare interface TextMeasurer {
766
822
  measureMm(text: string, options: TextMeasureOptions): number;
767
823
  }
768
824
 
825
+ /**
826
+ * RenderPlan → xlsx 导出(B 端第二出口,对齐家族 @agile-team/mach-table-xlsx 路线):
827
+ * - 网格组件 → 真表格:列宽(mm→Excel 宽度)、行高(mm→pt)、colSpan/rowSpan 合并、
828
+ * 加粗/对齐/底色/字号直译(resolveGridLayout 复用单真相源几何)
829
+ * - 文本组件 → 合并标题行(顺序流式输出,保字号/加粗/对齐;非像素级定位,
830
+ * 目标是"财务能直接用的对账表"而非复刻版面)
831
+ * - 未支持组件、富文本专有内容与单元格嵌套组件跳过并计入 warnings
832
+ */
833
+ declare interface XlsxRenderOptions {
834
+ /** 工作表命名(连续表默认使用标题,其余默认 "Sheet1" 起序)。 */
835
+ sheetName?: (sheetIndex: number) => string;
836
+ /** auto 默认将 wide 逻辑表合并为连续 Sheet;pages 保留逐页;continuous 要求明确的表来源。 */
837
+ sheetMode?: "auto" | "pages" | "continuous";
838
+ /** 宽表或连续表默认 raw,其余默认 text;显式配置可覆盖默认值。 */
839
+ valueMode?: "text" | "raw";
840
+ /** 连续表默认不限制打印纸型;显式 A3/A4/A5 仅设置打印适配,不改变 Excel 列宽。 */
841
+ paperSize?: "auto" | "a3" | "a4" | "a5";
842
+ }
843
+
769
844
  export { }