excel.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. 'use strict';
  2. const _ = require('lodash');
  3. const { sep } = require('path');
  4. const fs = require('fs');
  5. const Excel = require('exceljs');
  6. const moment = require('moment');
  7. const { CrudService } = require('naf-framework-mongoose/lib/service');
  8. const { BusinessError, ErrorCode } = require('naf-core').Error;
  9. class ExcelService extends CrudService {
  10. constructor(ctx) {
  11. super(ctx);
  12. this.root_path = _.get(this.ctx.app.config.export, 'root_path');
  13. this.file_type = 'export';
  14. if (!fs.existsSync(`${this.root_path}${this.file_type}`)) {
  15. // 如果不存在文件夹,就创建
  16. fs.mkdirSync(`${this.root_path}${this.file_type}`);
  17. }
  18. this.excel_path = `${sep}excel${sep}`;
  19. }
  20. /**
  21. * 导出excel;
  22. * @param {Object} param { data, meta, fn }
  23. * @property Object data 数据;有meta的形式就是正常数据直接用;没有meta情况,需要整理成行数据
  24. * @property meta 列设置; 若meta不存在,则逐行解析. meta存在,则直接自动解析
  25. * @property fn 文件名
  26. */
  27. async toExcel({ data = [], meta, fn = 'excel导出结果' } = {}) {
  28. const nowDate = new Date().getTime();
  29. const filename = `${fn}-${nowDate}.xlsx`;
  30. const path = `${this.root_path}${this.file_type}${this.excel_path}`;
  31. if (!path) {
  32. throw new BusinessError(ErrorCode.BUSINESS, '服务端没有设置存储路径');
  33. }
  34. if (!fs.existsSync(path)) {
  35. // 如果不存在文件夹,就创建
  36. fs.mkdirSync(path);
  37. }
  38. const workbook = new Excel.Workbook();
  39. const sheet = workbook.addWorksheet('sheet');
  40. if (meta) {
  41. sheet.columns = meta;
  42. sheet.addRows(data);
  43. } else {
  44. // 需要合并,每行数据就有scell,ecell,content为合并后的内容
  45. // 不需要合并,就没有scell,ecell,content是Object,以 单元格位置(A1):内容 的key:value形式保存
  46. for (const row of data) {
  47. const { scell, ecell, content, alignment, font } = row;
  48. if (scell && ecell) {
  49. sheet.mergeCells(scell, ecell);
  50. sheet.getCell(ecell).value = content;
  51. if (alignment) sheet.getCell(ecell).alignment = alignment;
  52. if (font) sheet.getCell(ecell).font = font;
  53. } else {
  54. if (_.isObject(content)) {
  55. const keys = Object.keys(content);
  56. for (const cell of keys) {
  57. const value = content[cell];
  58. sheet.getCell(cell).value = value;
  59. if (alignment) sheet.getCell(cell).alignment = alignment;
  60. if (font) sheet.getCell(cell).font = font;
  61. }
  62. }
  63. }
  64. }
  65. }
  66. // 导出
  67. const filepath = `${path}${filename}`;
  68. if (data.length <= 0) return;
  69. await workbook.xlsx.writeFile(filepath);
  70. // TODO 返回文件地址
  71. return `/file-zhwl/excel/${filename}`;
  72. }
  73. numberToLetter(num) {
  74. const arr = [ 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'Y' ];
  75. return arr[num];
  76. }
  77. }
  78. module.exports = ExcelService;