@nocobase/plugin-action-export 1.5.0-beta.9 → 1.5.1

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.
@@ -10,16 +10,16 @@
10
10
  module.exports = {
11
11
  "@formily/react": "2.3.0",
12
12
  "@formily/shared": "2.3.2",
13
- "@nocobase/client": "1.5.0-beta.9",
13
+ "@nocobase/client": "1.5.1",
14
14
  "react": "18.2.0",
15
15
  "@formily/antd-v5": "1.1.9",
16
16
  "react-i18next": "11.18.6",
17
17
  "lodash": "4.17.21",
18
18
  "file-saver": "2.0.5",
19
19
  "antd": "5.12.8",
20
- "@nocobase/server": "1.5.0-beta.9",
21
- "@nocobase/data-source-manager": "1.5.0-beta.9",
22
- "@nocobase/database": "1.5.0-beta.9",
23
- "@nocobase/actions": "1.5.0-beta.9",
24
- "async-mutex": "0.5.0"
20
+ "@nocobase/server": "1.5.1",
21
+ "@nocobase/actions": "1.5.1",
22
+ "@nocobase/database": "1.5.1",
23
+ "async-mutex": "0.5.0",
24
+ "@nocobase/data-source-manager": "1.5.1"
25
25
  };
@@ -1,7 +1,7 @@
1
1
  {
2
- "Export warning": "每次最多导出 {{limit}} 行数据,超出的将被忽略。",
3
- "Start export": "开始导出",
4
- "another export action is running, please try again later.": "另一导出任务正在运行,请稍后重试。",
2
+ "Export warning": "每次最多导出记录 {{limit}} 行数据,超出的将被忽略。",
3
+ "Start export": "开始导出记录",
4
+ "another export action is running, please try again later.": "另一导出记录任务正在运行,请稍后重试。",
5
5
  "True": "是",
6
6
  "False": "否"
7
7
  }
@@ -1 +1 @@
1
- {"name":"xlsx","version":"0.20.2","author":"sheetjs","description":"SheetJS Spreadsheet data parser and writer","keywords":["excel","xls","xlsx","xlsb","xlsm","ods","csv","dbf","dif","sylk","office","spreadsheet"],"bin":{"xlsx":"./bin/xlsx.njs"},"main":"xlsx.js","module":"xlsx.mjs","unpkg":"dist/xlsx.full.min.js","jsdelivr":"dist/xlsx.full.min.js","types":"types/index.d.ts","exports":{".":{"import":"./xlsx.mjs","require":"./xlsx.js","types":"./types/index.d.ts"},"./xlsx.mjs":{"import":"./xlsx.mjs","types":"./types/index.d.ts"},"./xlsx.js":{"require":"./xlsx.js","types":"./types/index.d.ts"},"./dist/xlsx.core.min":{"import":"./dist/xlsx.core.min.js","require":"./dist/xlsx.core.min.js","types":"./types/index.d.ts"},"./dist/xlsx.core.min.js":{"import":"./dist/xlsx.core.min.js","require":"./dist/xlsx.core.min.js","types":"./types/index.d.ts"},"./dist/xlsx.full.min":{"import":"./dist/xlsx.full.min.js","require":"./dist/xlsx.full.min.js","types":"./types/index.d.ts"},"./dist/xlsx.full.min.js":{"import":"./dist/xlsx.full.min.js","require":"./dist/xlsx.full.min.js","types":"./types/index.d.ts"},"./dist/xlsx.mini.min":{"import":"./dist/xlsx.mini.min.js","require":"./dist/xlsx.mini.min.js","types":"./types/index.d.ts"},"./dist/xlsx.mini.min.js":{"import":"./dist/xlsx.mini.min.js","require":"./dist/xlsx.mini.min.js","types":"./types/index.d.ts"},"./dist/xlsx.zahl":{"import":"./dist/xlsx.zahl.mjs","require":"./dist/xlsx.zahl.js","types":"./dist/zahl.d.ts"},"./dist/xlsx.zahl.mjs":{"import":"./dist/xlsx.zahl.mjs","types":"./dist/zahl.d.ts"},"./dist/xlsx.zahl.js":{"require":"./dist/xlsx.zahl.js","types":"./dist/zahl.d.ts"},"./dist/cpexcel":{"import":"./dist/cpexcel.full.mjs","require":"./dist/cpexcel.js","types":"./dist/cpexcel.d.ts"},"./dist/cpexcel.js":{"require":"./dist/cpexcel.js","types":"./dist/cpexcel.d.ts"},"./dist/cpexcel.full":{"import":"./dist/cpexcel.full.mjs","require":"./dist/cpexcel.js","types":"./dist/cpexcel.d.ts"},"./dist/cpexcel.full.mjs":{"import":"./dist/cpexcel.full.mjs","types":"./dist/cpexcel.d.ts"}},"browser":{"buffer":false,"crypto":false,"stream":false,"process":false,"fs":false},"sideEffects":false,"dependencies":{},"devDependencies":{"@sheetjs/uglify-js":"~2.7.3","@types/node":"^8.5.9","acorn":"7.4.1","adler-32":"~1.3.1","alex":"8.1.1","blanket":"~1.2.3","cfb":"~1.2.2","codepage":"~1.15.0","commander":"~2.17.1","crc-32":"~1.2.2","dtslint":"^0.1.2","eslint":"7.23.0","eslint-plugin-html":"^6.1.2","eslint-plugin-json":"^2.1.2","exit-on-epipe":"~1.0.1","fflate":"^0.7.1","jsdom":"~11.1.0","markdown-spellcheck":"^1.3.1","mocha":"~2.5.3","sinon":"^1.17.7","ssf":"~0.11.2","typescript":"2.2.0","wmf":"~1.0.1","word":"~0.3.0"},"repository":{"type":"git","url":"https://git.sheetjs.com/SheetJS/sheetjs"},"scripts":{"pretest":"npm run lint","test":"npm run tests-only","pretest-only":"git submodule init && git submodule update","tests-only":"make travis","build":"make","lint":"make fullint","dtslint":"dtslint types"},"config":{"blanket":{"pattern":"xlsx.js"}},"alex":{"allow":["chinese","special","simple","just","crash","wtf","holes"]},"homepage":"https://sheetjs.com/","files":["CHANGELOG.md","LICENSE","README.md","bower.json","package.json","xlsx.js","xlsx.mjs","xlsxworker.js","bin/xlsx.njs","dist/LICENSE","dist/*.mjs","dist/*.js","dist/*.map","dist/*.d.ts","types/index.d.ts","types/tsconfig.json"],"bugs":{"url":"https://git.sheetjs.com/SheetJS/sheetjs/issues"},"license":"Apache-2.0","engines":{"node":">=0.8"},"_lastModified":"2024-12-15T11:55:32.156Z"}
1
+ {"name":"xlsx","version":"0.20.2","author":"sheetjs","description":"SheetJS Spreadsheet data parser and writer","keywords":["excel","xls","xlsx","xlsb","xlsm","ods","csv","dbf","dif","sylk","office","spreadsheet"],"bin":{"xlsx":"./bin/xlsx.njs"},"main":"xlsx.js","module":"xlsx.mjs","unpkg":"dist/xlsx.full.min.js","jsdelivr":"dist/xlsx.full.min.js","types":"types/index.d.ts","exports":{".":{"import":"./xlsx.mjs","require":"./xlsx.js","types":"./types/index.d.ts"},"./xlsx.mjs":{"import":"./xlsx.mjs","types":"./types/index.d.ts"},"./xlsx.js":{"require":"./xlsx.js","types":"./types/index.d.ts"},"./dist/xlsx.core.min":{"import":"./dist/xlsx.core.min.js","require":"./dist/xlsx.core.min.js","types":"./types/index.d.ts"},"./dist/xlsx.core.min.js":{"import":"./dist/xlsx.core.min.js","require":"./dist/xlsx.core.min.js","types":"./types/index.d.ts"},"./dist/xlsx.full.min":{"import":"./dist/xlsx.full.min.js","require":"./dist/xlsx.full.min.js","types":"./types/index.d.ts"},"./dist/xlsx.full.min.js":{"import":"./dist/xlsx.full.min.js","require":"./dist/xlsx.full.min.js","types":"./types/index.d.ts"},"./dist/xlsx.mini.min":{"import":"./dist/xlsx.mini.min.js","require":"./dist/xlsx.mini.min.js","types":"./types/index.d.ts"},"./dist/xlsx.mini.min.js":{"import":"./dist/xlsx.mini.min.js","require":"./dist/xlsx.mini.min.js","types":"./types/index.d.ts"},"./dist/xlsx.zahl":{"import":"./dist/xlsx.zahl.mjs","require":"./dist/xlsx.zahl.js","types":"./dist/zahl.d.ts"},"./dist/xlsx.zahl.mjs":{"import":"./dist/xlsx.zahl.mjs","types":"./dist/zahl.d.ts"},"./dist/xlsx.zahl.js":{"require":"./dist/xlsx.zahl.js","types":"./dist/zahl.d.ts"},"./dist/cpexcel":{"import":"./dist/cpexcel.full.mjs","require":"./dist/cpexcel.js","types":"./dist/cpexcel.d.ts"},"./dist/cpexcel.js":{"require":"./dist/cpexcel.js","types":"./dist/cpexcel.d.ts"},"./dist/cpexcel.full":{"import":"./dist/cpexcel.full.mjs","require":"./dist/cpexcel.js","types":"./dist/cpexcel.d.ts"},"./dist/cpexcel.full.mjs":{"import":"./dist/cpexcel.full.mjs","types":"./dist/cpexcel.d.ts"}},"browser":{"buffer":false,"crypto":false,"stream":false,"process":false,"fs":false},"sideEffects":false,"dependencies":{},"devDependencies":{"@sheetjs/uglify-js":"~2.7.3","@types/node":"^8.5.9","acorn":"7.4.1","adler-32":"~1.3.1","alex":"8.1.1","blanket":"~1.2.3","cfb":"~1.2.2","codepage":"~1.15.0","commander":"~2.17.1","crc-32":"~1.2.2","dtslint":"^0.1.2","eslint":"7.23.0","eslint-plugin-html":"^6.1.2","eslint-plugin-json":"^2.1.2","exit-on-epipe":"~1.0.1","fflate":"^0.7.1","jsdom":"~11.1.0","markdown-spellcheck":"^1.3.1","mocha":"~2.5.3","sinon":"^1.17.7","ssf":"~0.11.2","typescript":"2.2.0","wmf":"~1.0.1","word":"~0.3.0"},"repository":{"type":"git","url":"https://git.sheetjs.com/SheetJS/sheetjs"},"scripts":{"pretest":"npm run lint","test":"npm run tests-only","pretest-only":"git submodule init && git submodule update","tests-only":"make travis","build":"make","lint":"make fullint","dtslint":"dtslint types"},"config":{"blanket":{"pattern":"xlsx.js"}},"alex":{"allow":["chinese","special","simple","just","crash","wtf","holes"]},"homepage":"https://sheetjs.com/","files":["CHANGELOG.md","LICENSE","README.md","bower.json","package.json","xlsx.js","xlsx.mjs","xlsxworker.js","bin/xlsx.njs","dist/LICENSE","dist/*.mjs","dist/*.js","dist/*.map","dist/*.d.ts","types/index.d.ts","types/tsconfig.json"],"bugs":{"url":"https://git.sheetjs.com/SheetJS/sheetjs/issues"},"license":"Apache-2.0","engines":{"node":">=0.8"},"_lastModified":"2025-02-06T03:44:14.483Z"}
@@ -7,4 +7,4 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import { Context, Next } from '@nocobase/actions';
10
- export declare function exportXlsx(ctx: Context, next: Next): Promise<void>;
10
+ export declare function exportXlsx(ctx: Context, next: Next): Promise<any>;
@@ -39,7 +39,7 @@ __export(export_xlsx_exports, {
39
39
  exportXlsx: () => exportXlsx
40
40
  });
41
41
  module.exports = __toCommonJS(export_xlsx_exports);
42
- var import_xlsx_exporter = __toESM(require("../xlsx-exporter"));
42
+ var import_xlsx_exporter = require("../services/xlsx-exporter");
43
43
  var import_xlsx = __toESM(require("xlsx"));
44
44
  var import_async_mutex = require("async-mutex");
45
45
  const mutex = new import_async_mutex.Mutex();
@@ -53,7 +53,7 @@ async function exportXlsxAction(ctx, next) {
53
53
  const repository = ctx.getCurrentRepository();
54
54
  const dataSource = ctx.dataSource;
55
55
  const collection = repository.collection;
56
- const xlsxExporter = new import_xlsx_exporter.default({
56
+ const xlsxExporter = new import_xlsx_exporter.XlsxExporter({
57
57
  collectionManager: dataSource.collectionManager,
58
58
  collection,
59
59
  repository,
@@ -73,6 +73,9 @@ async function exportXlsxAction(ctx, next) {
73
73
  });
74
74
  }
75
75
  async function exportXlsx(ctx, next) {
76
+ if (ctx.exportHandled) {
77
+ return await next();
78
+ }
76
79
  if (mutex.isLocked()) {
77
80
  throw new Error(
78
81
  ctx.t(`another export action is running, please try again later.`, {
@@ -12,3 +12,5 @@ export declare class PluginActionExportServer extends Plugin {
12
12
  load(): Promise<void>;
13
13
  }
14
14
  export default PluginActionExportServer;
15
+ export * from './services/base-exporter';
16
+ export * from './services/xlsx-exporter';
@@ -23,6 +23,7 @@ var __copyProps = (to, from, except, desc) => {
23
23
  }
24
24
  return to;
25
25
  };
26
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
26
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
28
  var server_exports = {};
28
29
  __export(server_exports, {
@@ -32,6 +33,8 @@ __export(server_exports, {
32
33
  module.exports = __toCommonJS(server_exports);
33
34
  var import_server = require("@nocobase/server");
34
35
  var import_actions = require("./actions");
36
+ __reExport(server_exports, require("./services/base-exporter"), module.exports);
37
+ __reExport(server_exports, require("./services/xlsx-exporter"), module.exports);
35
38
  class PluginActionExportServer extends import_server.Plugin {
36
39
  beforeLoad() {
37
40
  this.app.on("afterInstall", async () => {
@@ -64,7 +67,8 @@ class PluginActionExportServer extends import_server.Plugin {
64
67
  dataSource.resourceManager.registerActionHandler("export", import_actions.exportXlsx);
65
68
  dataSource.acl.setAvailableAction("export", {
66
69
  displayName: '{{t("Export")}}',
67
- allowConfigureFields: true
70
+ allowConfigureFields: true,
71
+ aliases: ["export", "exportAttachments"]
68
72
  });
69
73
  });
70
74
  }
@@ -72,5 +76,7 @@ class PluginActionExportServer extends import_server.Plugin {
72
76
  var server_default = PluginActionExportServer;
73
77
  // Annotate the CommonJS export names for ESM import in node:
74
78
  0 && (module.exports = {
75
- PluginActionExportServer
79
+ PluginActionExportServer,
80
+ ...require("./services/base-exporter"),
81
+ ...require("./services/xlsx-exporter")
76
82
  });
@@ -0,0 +1,40 @@
1
+ /// <reference types="node" />
2
+ import { FindOptions, ICollection, ICollectionManager, IField, IModel } from '@nocobase/data-source-manager';
3
+ import EventEmitter from 'events';
4
+ export type ExportOptions = {
5
+ collectionManager: ICollectionManager;
6
+ collection: ICollection;
7
+ repository?: any;
8
+ fields: Array<Array<string>>;
9
+ findOptions?: FindOptions;
10
+ chunkSize?: number;
11
+ limit?: number;
12
+ };
13
+ declare abstract class BaseExporter<T extends ExportOptions = ExportOptions> extends EventEmitter {
14
+ protected options: T;
15
+ /**
16
+ * You can adjust the maximum number of exported rows based on business needs and system
17
+ * available resources. However, please note that you need to fully understand the risks
18
+ * after the modification. Increasing the maximum number of rows that can be exported may
19
+ * increase system resource usage, leading to increased processing delays for other
20
+ * requests, or even server processes being recycled by the operating system.
21
+ *
22
+ * 您可以根据业务需求和系统可用资源等参数,调整最大导出数量的限制。但请注意,您需要充分了解修改之后的风险,
23
+ * 增加最大可导出的行数可能会导致系统资源占用率升高,导致其他请求处理延迟增加、无法处理、甚至
24
+ * 服务端进程被操作系统回收等问题。
25
+ */
26
+ protected limit: number;
27
+ protected constructor(options: T);
28
+ abstract init(ctx?: any): Promise<void>;
29
+ abstract finalize(): Promise<any>;
30
+ abstract handleRow(row: any, ctx?: any): Promise<void>;
31
+ run(ctx?: any): Promise<any>;
32
+ protected getAppendOptionsFromFields(): string[];
33
+ protected getFindOptions(): any;
34
+ protected findFieldByDataIndex(dataIndex: Array<string>): IField;
35
+ protected renderRawValue(value: any): any;
36
+ protected getFieldRenderer(field?: IField, ctx?: any): (value: any) => any;
37
+ protected formatValue(rowData: IModel, dataIndex: Array<string>, ctx?: any): any;
38
+ generateOutputPath(prefix?: string, ext?: string, destination?: string): string;
39
+ }
40
+ export { BaseExporter };
@@ -34,17 +34,20 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
34
  mod
35
35
  ));
36
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
- var xlsx_exporter_exports = {};
38
- __export(xlsx_exporter_exports, {
39
- default: () => xlsx_exporter_default
37
+ var base_exporter_exports = {};
38
+ __export(base_exporter_exports, {
39
+ BaseExporter: () => BaseExporter
40
40
  });
41
- module.exports = __toCommonJS(xlsx_exporter_exports);
42
- var import_xlsx = __toESM(require("xlsx"));
43
- var import_deep_get = require("./utils/deep-get");
44
- var import_database = require("@nocobase/database");
45
- class XlsxExporter {
41
+ module.exports = __toCommonJS(base_exporter_exports);
42
+ var import_events = __toESM(require("events"));
43
+ var import_deep_get = require("../utils/deep-get");
44
+ var import_path = __toESM(require("path"));
45
+ var import_os = __toESM(require("os"));
46
+ class BaseExporter extends import_events.default {
46
47
  constructor(options) {
48
+ super();
47
49
  this.options = options;
50
+ this.limit = options.limit ?? (process.env["EXPORT_LIMIT"] ? parseInt(process.env["EXPORT_LIMIT"]) : 2e3);
48
51
  }
49
52
  /**
50
53
  * You can adjust the maximum number of exported rows based on business needs and system
@@ -57,68 +60,46 @@ class XlsxExporter {
57
60
  * 增加最大可导出的行数可能会导致系统资源占用率升高,导致其他请求处理延迟增加、无法处理、甚至
58
61
  * 服务端进程被操作系统回收等问题。
59
62
  */
60
- limit = process.env["EXPORT_LIMIT"] ? parseInt(process.env["EXPORT_LIMIT"]) : 2e3;
63
+ limit;
61
64
  async run(ctx) {
62
- const { collection, columns, chunkSize, repository } = this.options;
63
- const workbook = import_xlsx.default.utils.book_new();
64
- const worksheet = import_xlsx.default.utils.sheet_new();
65
- import_xlsx.default.utils.sheet_add_aoa(worksheet, [this.renderHeaders()], {
66
- origin: "A1"
67
- });
68
- let startRowNumber = 2;
65
+ await this.init(ctx);
66
+ const { collection, chunkSize, repository } = this.options;
67
+ const total = await (repository || collection.repository).count(this.getFindOptions());
68
+ let current = 0;
69
69
  await (repository || collection.repository).chunk({
70
70
  ...this.getFindOptions(),
71
71
  chunkSize: chunkSize || 200,
72
72
  callback: async (rows, options) => {
73
- const chunkData = rows.map((r) => {
74
- return columns.map((col) => {
75
- return this.renderCellValue(r, col, ctx);
73
+ for (const row of rows) {
74
+ await this.handleRow(row, ctx);
75
+ current += 1;
76
+ this.emit("progress", {
77
+ total,
78
+ current
76
79
  });
77
- });
78
- import_xlsx.default.utils.sheet_add_aoa(worksheet, chunkData, {
79
- origin: `A${startRowNumber}`
80
- });
81
- startRowNumber += rows.length;
82
- await new Promise((resolve) => {
83
- setTimeout(resolve, 50);
84
- });
85
- }
86
- });
87
- for (const col of columns) {
88
- const field = this.findFieldByDataIndex(col.dataIndex);
89
- if (field instanceof import_database.NumberField) {
90
- const colIndex = columns.indexOf(col);
91
- const cellRange = import_xlsx.default.utils.decode_range(worksheet["!ref"]);
92
- for (let r = 1; r <= cellRange.e.r; r++) {
93
- const cell = worksheet[import_xlsx.default.utils.encode_cell({ c: colIndex, r })];
94
- if (cell && isNumeric(cell.v)) {
95
- cell.t = "n";
96
- }
97
80
  }
98
81
  }
99
- }
100
- import_xlsx.default.utils.book_append_sheet(workbook, worksheet, "Data");
101
- return workbook;
82
+ });
83
+ return this.finalize();
102
84
  }
103
- getAppendOptionsFromColumns() {
104
- return this.options.columns.map((col) => {
105
- if (col.dataIndex.length > 1) {
106
- return col.dataIndex.join(".");
107
- }
108
- const field = this.options.collection.getField(col.dataIndex[0]);
109
- if (!field) {
110
- throw new Error(`Field "${col.dataIndex[0]}" not found: , please check the columns configuration.`);
85
+ getAppendOptionsFromFields() {
86
+ return this.options.fields.map((field) => {
87
+ const fieldInstance = this.options.collection.getField(field[0]);
88
+ if (!fieldInstance) {
89
+ throw new Error(`Field "${field[0]}" not found: , please check the fields configuration.`);
111
90
  }
112
- if (field.isRelationField()) {
113
- return col.dataIndex[0];
91
+ if (fieldInstance.isRelationField()) {
92
+ return field.join(".");
114
93
  }
115
94
  return null;
116
95
  }).filter(Boolean);
117
96
  }
118
97
  getFindOptions() {
119
98
  const { findOptions = {} } = this.options;
120
- findOptions.limit = this.limit;
121
- const appendOptions = this.getAppendOptionsFromColumns();
99
+ if (this.limit) {
100
+ findOptions.limit = this.limit;
101
+ }
102
+ const appendOptions = this.getAppendOptionsFromFields();
122
103
  if (appendOptions.length) {
123
104
  return {
124
105
  ...findOptions,
@@ -142,15 +123,6 @@ class XlsxExporter {
142
123
  }
143
124
  return currentField;
144
125
  }
145
- renderHeaders() {
146
- return this.options.columns.map((col) => {
147
- const field = this.findFieldByDataIndex(col.dataIndex);
148
- if (col.title) {
149
- return col.title;
150
- }
151
- return (field == null ? void 0 : field.options.title) || col.defaultTitle;
152
- });
153
- }
154
126
  renderRawValue(value) {
155
127
  if (typeof value === "object" && value !== null) {
156
128
  return JSON.stringify(value);
@@ -163,11 +135,10 @@ class XlsxExporter {
163
135
  if (!InterfaceClass) {
164
136
  return this.renderRawValue;
165
137
  }
166
- const fieldInternface = new InterfaceClass(field == null ? void 0 : field.options);
167
- return (value) => fieldInternface.toString(value, ctx);
138
+ const fieldInterface = new InterfaceClass(field == null ? void 0 : field.options);
139
+ return (value) => fieldInterface.toString(value, ctx);
168
140
  }
169
- renderCellValue(rowData, column, ctx) {
170
- const { dataIndex } = column;
141
+ formatValue(rowData, dataIndex, ctx) {
171
142
  rowData = rowData.toJSON();
172
143
  const value = rowData[dataIndex[0]];
173
144
  const field = this.findFieldByDataIndex(dataIndex);
@@ -181,8 +152,12 @@ class XlsxExporter {
181
152
  }
182
153
  return render(value);
183
154
  }
155
+ generateOutputPath(prefix = "export", ext = "", destination = import_os.default.tmpdir()) {
156
+ const fileName = `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2)}${ext}`;
157
+ return import_path.default.join(destination, fileName);
158
+ }
184
159
  }
185
- function isNumeric(n) {
186
- return !isNaN(parseFloat(n)) && isFinite(n);
187
- }
188
- var xlsx_exporter_default = XlsxExporter;
160
+ // Annotate the CommonJS export names for ESM import in node:
161
+ 0 && (module.exports = {
162
+ BaseExporter
163
+ });
@@ -1,28 +1,16 @@
1
- /**
2
- * This file is part of the NocoBase (R) project.
3
- * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
- * Authors: NocoBase Team.
5
- *
6
- * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
- * For more information, please refer to: https://www.nocobase.com/agreement.
8
- */
9
- import { FindOptions, ICollection, ICollectionManager } from '@nocobase/data-source-manager';
10
1
  import XLSX from 'xlsx';
2
+ import { BaseExporter, ExportOptions } from './base-exporter';
11
3
  type ExportColumn = {
12
4
  dataIndex: Array<string>;
13
5
  title?: string;
14
6
  defaultTitle: string;
15
7
  };
16
- type ExportOptions = {
17
- collectionManager: ICollectionManager;
18
- collection: ICollection;
19
- repository?: any;
8
+ type XlsxExportOptions = Omit<ExportOptions, 'fields'> & {
20
9
  columns: Array<ExportColumn>;
21
- findOptions?: FindOptions;
22
- chunkSize?: number;
23
10
  };
24
- declare class XlsxExporter {
25
- private options;
11
+ export declare class XlsxExporter extends BaseExporter<XlsxExportOptions & {
12
+ fields: Array<Array<string>>;
13
+ }> {
26
14
  /**
27
15
  * You can adjust the maximum number of exported rows based on business needs and system
28
16
  * available resources. However, please note that you need to fully understand the risks
@@ -34,15 +22,13 @@ declare class XlsxExporter {
34
22
  * 增加最大可导出的行数可能会导致系统资源占用率升高,导致其他请求处理延迟增加、无法处理、甚至
35
23
  * 服务端进程被操作系统回收等问题。
36
24
  */
37
- limit: number;
38
- constructor(options: ExportOptions);
39
- run(ctx?: any): Promise<XLSX.WorkBook>;
40
- private getAppendOptionsFromColumns;
41
- private getFindOptions;
42
- private findFieldByDataIndex;
25
+ private workbook;
26
+ private worksheet;
27
+ private startRowNumber;
28
+ constructor(options: XlsxExportOptions);
29
+ init(ctx?: any): Promise<void>;
30
+ handleRow(row: any, ctx?: any): Promise<void>;
31
+ finalize(): Promise<XLSX.WorkBook>;
43
32
  private renderHeaders;
44
- private renderRawValue;
45
- private getFieldRenderer;
46
- private renderCellValue;
47
33
  }
48
- export default XlsxExporter;
34
+ export {};
@@ -0,0 +1,113 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var xlsx_exporter_exports = {};
38
+ __export(xlsx_exporter_exports, {
39
+ XlsxExporter: () => XlsxExporter
40
+ });
41
+ module.exports = __toCommonJS(xlsx_exporter_exports);
42
+ var import_xlsx = __toESM(require("xlsx"));
43
+ var import_base_exporter = require("./base-exporter");
44
+ var import_database = require("@nocobase/database");
45
+ class XlsxExporter extends import_base_exporter.BaseExporter {
46
+ /**
47
+ * You can adjust the maximum number of exported rows based on business needs and system
48
+ * available resources. However, please note that you need to fully understand the risks
49
+ * after the modification. Increasing the maximum number of rows that can be exported may
50
+ * increase system resource usage, leading to increased processing delays for other
51
+ * requests, or even server processes being recycled by the operating system.
52
+ *
53
+ * 您可以根据业务需求和系统可用资源等参数,调整最大导出数量的限制。但请注意,您需要充分了解修改之后的风险,
54
+ * 增加最大可导出的行数可能会导致系统资源占用率升高,导致其他请求处理延迟增加、无法处理、甚至
55
+ * 服务端进程被操作系统回收等问题。
56
+ */
57
+ workbook;
58
+ worksheet;
59
+ startRowNumber;
60
+ constructor(options) {
61
+ const fields = options.columns.map((col) => col.dataIndex);
62
+ super({ ...options, fields });
63
+ }
64
+ async init(ctx) {
65
+ this.workbook = import_xlsx.default.utils.book_new();
66
+ this.worksheet = import_xlsx.default.utils.sheet_new();
67
+ import_xlsx.default.utils.sheet_add_aoa(this.worksheet, [this.renderHeaders(this.options.columns)], {
68
+ origin: "A1"
69
+ });
70
+ this.startRowNumber = 2;
71
+ }
72
+ async handleRow(row, ctx) {
73
+ const rowData = [
74
+ this.options.columns.map((col) => {
75
+ return this.formatValue(row, col.dataIndex, ctx);
76
+ })
77
+ ];
78
+ import_xlsx.default.utils.sheet_add_aoa(this.worksheet, rowData, {
79
+ origin: `A${this.startRowNumber}`
80
+ });
81
+ this.startRowNumber += 1;
82
+ }
83
+ async finalize() {
84
+ for (const col of this.options.columns) {
85
+ const fieldInstance = this.findFieldByDataIndex(col.dataIndex);
86
+ if (fieldInstance instanceof import_database.NumberField) {
87
+ const colIndex = this.options.columns.indexOf(col);
88
+ const cellRange = import_xlsx.default.utils.decode_range(this.worksheet["!ref"]);
89
+ for (let r = 1; r <= cellRange.e.r; r++) {
90
+ const cell = this.worksheet[import_xlsx.default.utils.encode_cell({ c: colIndex, r })];
91
+ if (cell && isNumeric(cell.v)) {
92
+ cell.t = "n";
93
+ }
94
+ }
95
+ }
96
+ }
97
+ import_xlsx.default.utils.book_append_sheet(this.workbook, this.worksheet, "Data");
98
+ return this.workbook;
99
+ }
100
+ renderHeaders(columns) {
101
+ return columns.map((col) => {
102
+ const fieldInstance = this.findFieldByDataIndex(col.dataIndex);
103
+ return col.title || (fieldInstance == null ? void 0 : fieldInstance.options.title) || col.defaultTitle;
104
+ });
105
+ }
106
+ }
107
+ function isNumeric(n) {
108
+ return !isNaN(parseFloat(n)) && isFinite(n);
109
+ }
110
+ // Annotate the CommonJS export names for ESM import in node:
111
+ 0 && (module.exports = {
112
+ XlsxExporter
113
+ });
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName.zh-CN": "操作:导出记录",
5
5
  "description": "Export filtered records to excel, you can configure which fields to export.",
6
6
  "description.zh-CN": "导出筛选后的记录到 Excel 中,可以配置导出哪些字段。",
7
- "version": "1.5.0-beta.9",
7
+ "version": "1.5.1",
8
8
  "license": "AGPL-3.0",
9
9
  "main": "./dist/server/index.js",
10
10
  "homepage": "https://docs.nocobase.com/handbook/action-export",
@@ -29,7 +29,7 @@
29
29
  "@nocobase/test": "1.x",
30
30
  "@nocobase/utils": "1.x"
31
31
  },
32
- "gitHead": "fef0bcb5f95705cd83607f03a6c911550016281b",
32
+ "gitHead": "b16a0ff226482d0de847656ea26fd621b1d685cf",
33
33
  "keywords": [
34
34
  "Actions"
35
35
  ]