ExportExcel.js 4.9 KB

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