Export2Excel.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. import { saveAs } from "file-saver";
  2. import * as XLSX from "xlsx";
  3. function generateArray(table) {
  4. var out = [];
  5. var rows = table.querySelectorAll("tr");
  6. var ranges = [];
  7. for (var R = 0; R < rows.length; ++R) {
  8. var outRow = [];
  9. var row = rows[R];
  10. var columns = row.querySelectorAll("td");
  11. for (var C = 0; C < columns.length; ++C) {
  12. var cell = columns[C];
  13. var colspan = cell.getAttribute("colspan");
  14. var rowspan = cell.getAttribute("rowspan");
  15. var cellValue = cell.innerText;
  16. if (cellValue !== "" && cellValue === +cellValue) cellValue = +cellValue;
  17. //Skip ranges
  18. ranges.forEach(function (range) {
  19. if (
  20. R >= range.s.r &&
  21. R <= range.e.r &&
  22. outRow.length >= range.s.c &&
  23. outRow.length <= range.e.c
  24. ) {
  25. for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
  26. }
  27. });
  28. //Handle Row Span
  29. if (rowspan || colspan) {
  30. rowspan = rowspan || 1;
  31. colspan = colspan || 1;
  32. ranges.push({
  33. s: {
  34. r: R,
  35. c: outRow.length,
  36. },
  37. e: {
  38. r: R + rowspan - 1,
  39. c: outRow.length + colspan - 1,
  40. },
  41. });
  42. }
  43. //Handle Value
  44. outRow.push(cellValue !== "" ? cellValue : null);
  45. //Handle Colspan
  46. if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
  47. }
  48. out.push(outRow);
  49. }
  50. return [out, ranges];
  51. }
  52. function datenum(v, date1904) {
  53. if (date1904) v += 1462;
  54. var epoch = Date.parse(v);
  55. return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
  56. }
  57. function sheet_from_array_of_arrays(data, opts) {
  58. var ws = {};
  59. var range = {
  60. s: {
  61. c: 10000000,
  62. r: 10000000,
  63. },
  64. e: {
  65. c: 0,
  66. r: 0,
  67. },
  68. };
  69. for (var R = 0; R != data.length; ++R) {
  70. for (var C = 0; C != data[R].length; ++C) {
  71. if (range.s.r > R) range.s.r = R;
  72. if (range.s.c > C) range.s.c = C;
  73. if (range.e.r < R) range.e.r = R;
  74. if (range.e.c < C) range.e.c = C;
  75. var cell = {
  76. v: data[R][C],
  77. };
  78. if (cell.v == null) continue;
  79. var cell_ref = XLSX.utils.encode_cell({
  80. c: C,
  81. r: R,
  82. });
  83. if (typeof cell.v === "number") cell.t = "n";
  84. else if (typeof cell.v === "boolean") cell.t = "b";
  85. else if (cell.v instanceof Date) {
  86. cell.t = "n";
  87. cell.z = XLSX.SSF._table[14];
  88. cell.v = datenum(cell.v);
  89. } else cell.t = "s";
  90. ws[cell_ref] = cell;
  91. }
  92. }
  93. if (range.s.c < 10000000) ws["!ref"] = XLSX.utils.encode_range(range);
  94. return ws;
  95. }
  96. function Workbook() {
  97. if (!(this instanceof Workbook)) return new Workbook();
  98. this.SheetNames = [];
  99. this.Sheets = {};
  100. }
  101. function s2ab(s) {
  102. var buf = new ArrayBuffer(s.length);
  103. var view = new Uint8Array(buf);
  104. for (var i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
  105. return buf;
  106. }
  107. export function export_table_to_excel(id) {
  108. var theTable = document.getElementById(id);
  109. var oo = generateArray(theTable);
  110. var ranges = oo[1];
  111. /* original data */
  112. var data = oo[0];
  113. var ws_name = "SheetJS";
  114. var wb = new Workbook(),
  115. ws = sheet_from_array_of_arrays(data);
  116. /* add ranges to worksheet */
  117. // ws['!cols'] = ['apple', 'banan'];
  118. ws["!merges"] = ranges;
  119. /* add worksheet to workbook */
  120. wb.SheetNames.push(ws_name);
  121. wb.Sheets[ws_name] = ws;
  122. var wbout = XLSX.write(wb, {
  123. bookType: "xlsx",
  124. bookSST: false,
  125. type: "binary",
  126. });
  127. saveAs(
  128. new Blob([s2ab(wbout)], {
  129. type: "application/octet-stream",
  130. }),
  131. "test.xlsx"
  132. );
  133. }
  134. export function export_json_to_excel({
  135. multiHeader = [],
  136. header,
  137. data,
  138. filename,
  139. merges = [],
  140. autoWidth = true,
  141. bookType = "xlsx",
  142. } = {}) {
  143. /* original data */
  144. filename = filename || "excel-list";
  145. data = [...data];
  146. data.unshift(header);
  147. for (let i = multiHeader.length - 1; i > -1; i--) {
  148. data.unshift(multiHeader[i]);
  149. }
  150. var ws_name = "Sheet1";
  151. var wb = new Workbook(),
  152. ws = sheet_from_array_of_arrays(data);
  153. if (merges.length > 0) {
  154. if (!ws["!merges"]) ws["!merges"] = [];
  155. merges.forEach((item) => {
  156. ws["!merges"].push(XLSX.utils.decode_range(item));
  157. });
  158. }
  159. if (autoWidth) {
  160. /*设置worksheet每列的最大宽度*/
  161. const colWidth = data.map((row) =>
  162. row.map((val) => {
  163. /*先判断是否为null/undefined*/
  164. if (val == null) {
  165. return {
  166. wch: 10,
  167. };
  168. } else if (val.toString().charCodeAt(0) > 255) {
  169. /*再判断是否为中文*/
  170. return {
  171. wch: val.toString().length * 2,
  172. };
  173. } else {
  174. return {
  175. wch: val.toString().length,
  176. };
  177. }
  178. })
  179. );
  180. /*以第一行为初始值*/
  181. let result = colWidth[0];
  182. for (let i = 1; i < colWidth.length; i++) {
  183. for (let j = 0; j < colWidth[i].length; j++) {
  184. if (result[j]["wch"] < colWidth[i][j]["wch"]) {
  185. result[j]["wch"] = colWidth[i][j]["wch"];
  186. }
  187. }
  188. }
  189. ws["!cols"] = result;
  190. }
  191. /* add worksheet to workbook */
  192. wb.SheetNames.push(ws_name);
  193. wb.Sheets[ws_name] = ws;
  194. var wbout = XLSX.write(wb, {
  195. bookType: bookType,
  196. bookSST: false,
  197. type: "binary",
  198. });
  199. saveAs(
  200. new Blob([s2ab(wbout)], {
  201. type: "application/octet-stream",
  202. }),
  203. `${filename}.${bookType}`
  204. );
  205. }