CCL_QMS检验
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
5.6 KiB

  1. import XLSX from "xlsx";
  2. import ajax from '@/utils/ajax'
  3. import {
  4. Message
  5. } from 'element-ui';
  6. const excelHeaderName = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
  7. /**
  8. * excel导出默认选项
  9. */
  10. const exportOptionDefault = {
  11. url: "",//*必填,导出请求地址
  12. tableRef: undefined,//#1组合必填 导出数据对应列信息,el-table引用
  13. columnMapping: undefined,//#1组合必填 自定义导出列映射
  14. fileName: "export.xlsx",//导出文件名
  15. params: {},//导出请求参数
  16. rowFetcher: res => {//从请求结果中获取导出行的方式,默认取请求结果中的data作为导出数据
  17. return (res || {data: []}).data;
  18. },
  19. columnFormatter: [],//需要格式化的列
  20. mergeSetting: {
  21. refs: [], //检测需要合并的数据列属性名
  22. columns: [] //检测需要合并后,要合并的列,以第一条数据为准合并
  23. },
  24. dropColumns: [],//导出时需要过滤掉的列
  25. };
  26. let HEADERS = [];
  27. for (let i =0;i< 200;i++) {
  28. let c = parseInt(i / 26);
  29. let m = i % 26;
  30. HEADERS.push((c > 0 ? excelHeaderName[c - 1] : "") + excelHeaderName[m]);
  31. }
  32. let validOption = opt => {
  33. let option = Object.assign({}, opt);
  34. if (!option.url) {
  35. throw new Error("request url is required.");
  36. }
  37. if (!option.tableRef && !option.columnMapping) {
  38. throw new Error("element table ref object or columnMapping is required.");
  39. }
  40. if (option.rowFetcher != undefined && typeof option.rowFetcher != "function") {
  41. throw new Error("rowFetcher must be a function with one param.");
  42. }
  43. }
  44. let getMergeSetting = (data, s, allCols) => {
  45. let refCols = s.refs;
  46. let mcols = s.columns;
  47. let mergeList = [];
  48. let refRow = data[0];
  49. let mergeSetting = {
  50. s: 0,
  51. e: 0
  52. };
  53. for (let i = 0; i < data.length; i++) {
  54. let same = refCols.map(c => data[i][c] === refRow[c]).filter(r => !!r).length == refCols.length;
  55. if (!same) {
  56. mergeSetting.e > mergeSetting.s && (mergeList.push(mergeSetting));
  57. refRow = data[i];
  58. mergeSetting = {
  59. s: i,
  60. e: i
  61. };
  62. } else {
  63. i > mergeSetting.e && (mergeSetting.e = i);
  64. i == data.length - 1 && (mergeList.push(mergeSetting));
  65. }
  66. }
  67. let setting = [];
  68. mergeList.forEach(e => {
  69. mcols.forEach(c => {
  70. let ci = allCols.indexOf(c);
  71. setting.push({
  72. s: {
  73. r: e.s + 1,
  74. c: ci
  75. },
  76. e: {
  77. r: e.e + 1,
  78. c: ci
  79. }
  80. });
  81. });
  82. });
  83. return setting;
  84. }
  85. let setStyle = (ws, s) => {}
  86. let getColSetting = (mapping,dropColums) => {
  87. let columns = [];
  88. for (let i = 0; i < mapping.length; i++) {
  89. let c = mapping[i];
  90. if (dropColums.indexOf(c.columnProp) == -1) {
  91. columns.push({
  92. property: c.columnProp || c.property,
  93. label: c.columnLabel,
  94. type: "default"
  95. });
  96. }
  97. }
  98. return {
  99. columns: columns
  100. };
  101. }
  102. let export2Excel = opt => {
  103. validOption(opt);
  104. let options = Object.assign({}, exportOptionDefault, opt);
  105. let expColSetting = !!options.tableRef ? options.tableRef : getColSetting(options.columnMapping, options.dropColumns);
  106. ajax.$post(options.url, options.params, resp => {
  107. if (resp.status !== 200) {
  108. Message.error({
  109. message: resp.description
  110. });
  111. }
  112. let rows = !!resp.data.rows?options.rowFetcher(resp).rows:resp.data.page.list;
  113. if (!rows || rows.length === 0) {
  114. Message.warning({
  115. message: '没有数据可导出'
  116. });
  117. return;
  118. }
  119. var columns = [
  120. []
  121. ];
  122. var keys = [];
  123. let formaters = new Array();
  124. expColSetting.columns.forEach(column => {
  125. if (!!column.label && column.type === "default") {
  126. columns[0].push(column.label);
  127. keys.push(column.property);
  128. let formater = options.columnFormatter.find(f => !!f[column.property] && typeof f[column.property] == 'function');
  129. !!formater && (formaters[column.property] = formater[column.property]);
  130. }
  131. });
  132. rows.forEach(o => {
  133. let list = [];
  134. keys.forEach(k => {
  135. let formater = formaters[k];
  136. if (!!formater) {
  137. list.push(formater(o[k]));
  138. } else {
  139. list.push(o[k]);
  140. }
  141. });
  142. columns.push(list);
  143. });
  144. const ws = XLSX.utils.aoa_to_sheet(columns);
  145. if (!!options.mergeSetting && !!options.mergeSetting.refs && options.mergeSetting.refs.length > 0) {
  146. let merges = getMergeSetting(rows, options.mergeSetting, keys);
  147. ws["!merges"] = merges;
  148. setStyle(ws, merges);
  149. }
  150. // console.log(ws);
  151. const wb = XLSX.utils.book_new();
  152. // Excel sheet名称限制:最大31个字符,且不能包含 \ / ? * [ ]
  153. let sheetName = options.fileName
  154. .replace(/\.xlsx/, "")
  155. .replace(/[\\\/\?\*\[\]]/g, "");
  156. // 限制31字符
  157. if (sheetName.length > 31) {
  158. sheetName = sheetName.substring(0, 31);
  159. }
  160. XLSX.utils.book_append_sheet(
  161. wb,
  162. ws,
  163. sheetName
  164. );
  165. XLSX.writeFile(wb, options.fileName);
  166. });
  167. }
  168. export default {
  169. exportTable: export2Excel
  170. }