export.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // import { createCellPos } from './translateNumToLetter'
  2. const Excel = require("exceljs");
  3. import FileSaver from "file-saver";
  4. export var exportExcel = function (luckysheet, value) {
  5. // 参数为luckysheet.getluckysheetfile()获取的对象
  6. // 1.创建工作簿,可以为工作簿添加属性
  7. const workbook = new Excel.Workbook();
  8. // 2.创建表格,第二个参数可以配置创建什么样的工作表
  9. if (Object.prototype.toString.call(luckysheet) === "[object Object]") {
  10. luckysheet = [luckysheet];
  11. }
  12. luckysheet.forEach(function (table) {
  13. if (table.data.length === 0) return true;
  14. // ws.getCell('B2').fill = fills.
  15. const worksheet = workbook.addWorksheet(table.name);
  16. const merge = (table.config && table.config.merge) || {};
  17. const borderInfo = (table.config && table.config.borderInfo) || {};
  18. // 3.设置单元格合并,设置单元格边框,设置单元格样式,设置值
  19. setStyleAndValue(table.data, worksheet);
  20. setMerge(merge, worksheet);
  21. setBorder(borderInfo, worksheet);
  22. return true;
  23. });
  24. // return
  25. // 4.写入 buffer
  26. const buffer = workbook.xlsx.writeBuffer().then((data) => {
  27. // console.log('data', data)
  28. const blob = new Blob([data], {
  29. type: "application/vnd.ms-excel;charset=utf-8",
  30. });
  31. console.log("导出成功!");
  32. FileSaver.saveAs(blob, `${value}.xlsx`);
  33. });
  34. return buffer;
  35. };
  36. var setMerge = function (luckyMerge = {}, worksheet) {
  37. const mergearr = Object.values(luckyMerge);
  38. mergearr.forEach(function (elem) {
  39. // elem格式:{r: 0, c: 0, rs: 1, cs: 2}
  40. // 按开始行,开始列,结束行,结束列合并(相当于 K10:M12)
  41. worksheet.mergeCells(
  42. elem.r + 1,
  43. elem.c + 1,
  44. elem.r + elem.rs,
  45. elem.c + elem.cs
  46. );
  47. });
  48. };
  49. var setBorder = function (luckyBorderInfo, worksheet) {
  50. if (!Array.isArray(luckyBorderInfo)) return;
  51. // console.log('luckyBorderInfo', luckyBorderInfo)
  52. luckyBorderInfo.forEach(function (elem) {
  53. // 现在只兼容到borderType 为range的情况
  54. // console.log('ele', elem)
  55. if (elem.rangeType === "range") {
  56. let border = borderConvert(elem.borderType, elem.style, elem.color);
  57. let rang = elem.range[0];
  58. // console.log('range', rang)
  59. let row = rang.row;
  60. let column = rang.column;
  61. for (let i = row[0] + 1; i < row[1] + 2; i++) {
  62. for (let y = column[0] + 1; y < column[1] + 2; y++) {
  63. worksheet.getCell(i, y).border = border;
  64. }
  65. }
  66. }
  67. if (elem.rangeType === "cell") {
  68. // col_index: 2
  69. // row_index: 1
  70. // b: {
  71. // color: '#d0d4e3'
  72. // style: 1
  73. // }
  74. const { col_index, row_index } = elem.value;
  75. const borderData = Object.assign({}, elem.value);
  76. delete borderData.col_index;
  77. delete borderData.row_index;
  78. let border = addborderToCell(borderData, row_index, col_index);
  79. // console.log('bordre', border, borderData)
  80. worksheet.getCell(row_index + 1, col_index + 1).border = border;
  81. }
  82. // console.log(rang.column_focus + 1, rang.row_focus + 1)
  83. // worksheet.getCell(rang.row_focus + 1, rang.column_focus + 1).border = border
  84. });
  85. };
  86. var setStyleAndValue = function (cellArr, worksheet) {
  87. if (!Array.isArray(cellArr)) return;
  88. cellArr.forEach(function (row, rowid) {
  89. row.every(function (cell, columnid) {
  90. if (!cell) return true;
  91. let fill = fillConvert(cell.bg);
  92. let font = fontConvert(
  93. cell.ff,
  94. cell.fc,
  95. cell.bl,
  96. cell.it,
  97. cell.fs,
  98. cell.cl,
  99. cell.ul
  100. );
  101. let alignment = alignmentConvert(
  102. cell.vt,
  103. cell.ht,
  104. cell.tb,
  105. cell.tr
  106. );
  107. let value = "";
  108. if (cell.f) {
  109. value = { formula: cell.f, result: cell.v };
  110. } else if (!cell.v && cell.ct && cell.ct.s) {
  111. // xls转为xlsx之后,内部存在不同的格式,都会进到富文本里,即值不存在与cell.v,而是存在于cell.ct.s之后
  112. // value = cell.ct.s[0].v
  113. cell.ct.s.forEach((arr) => {
  114. value += arr.v;
  115. });
  116. } else {
  117. value = cell.v;
  118. }
  119. // style 填入到_value中可以实现填充色
  120. let letter = createCellPos(columnid);
  121. let target = worksheet.getCell(letter + (rowid + 1));
  122. // console.log('1233', letter + (rowid + 1))
  123. // eslint-disable-next-line no-unused-vars
  124. for (const key in fill) {
  125. target.fill = fill;
  126. break;
  127. }
  128. target.font = font;
  129. target.alignment = alignment;
  130. target.value = value;
  131. return true;
  132. });
  133. });
  134. };
  135. var fillConvert = function (bg) {
  136. if (!bg) {
  137. return {};
  138. }
  139. // const bgc = bg.replace('#', '')
  140. let fill = {
  141. type: "pattern",
  142. pattern: "solid",
  143. fgColor: { argb: bg.replace("#", "") },
  144. };
  145. return fill;
  146. };
  147. var fontConvert = function (
  148. ff = 0,
  149. fc = "#000000",
  150. bl = 0,
  151. it = 0,
  152. fs = 10,
  153. cl = 0,
  154. ul = 0
  155. ) {
  156. // luckysheet:ff(样式), fc(颜色), bl(粗体), it(斜体), fs(大小), cl(删除线), ul(下划线)
  157. const luckyToExcel = {
  158. 0: "微软雅黑",
  159. 1: "宋体(Song)",
  160. 2: "黑体(ST Heiti)",
  161. 3: "楷体(ST Kaiti)",
  162. 4: "仿宋(ST FangSong)",
  163. 5: "新宋体(ST Song)",
  164. 6: "华文新魏",
  165. 7: "华文行楷",
  166. 8: "华文隶书",
  167. 9: "Arial",
  168. 10: "Times New Roman ",
  169. 11: "Tahoma ",
  170. 12: "Verdana",
  171. num2bl: function (num) {
  172. return num === 0 ? false : true;
  173. },
  174. };
  175. // 出现Bug,导入的时候ff为luckyToExcel的val
  176. let font = {
  177. name: typeof ff === "number" ? luckyToExcel[ff] : ff,
  178. family: 1,
  179. size: fs,
  180. color: { argb: fc.replace("#", "") },
  181. bold: luckyToExcel.num2bl(bl),
  182. italic: luckyToExcel.num2bl(it),
  183. underline: luckyToExcel.num2bl(ul),
  184. strike: luckyToExcel.num2bl(cl),
  185. };
  186. return font;
  187. };
  188. var alignmentConvert = function (
  189. vt = "default",
  190. ht = "default",
  191. tb = "default",
  192. tr = "default"
  193. ) {
  194. // luckysheet:vt(垂直), ht(水平), tb(换行), tr(旋转)
  195. const luckyToExcel = {
  196. vertical: {
  197. 0: "middle",
  198. 1: "top",
  199. 2: "bottom",
  200. default: "top",
  201. },
  202. horizontal: {
  203. 0: "center",
  204. 1: "left",
  205. 2: "right",
  206. default: "left",
  207. },
  208. wrapText: {
  209. 0: false,
  210. 1: false,
  211. 2: true,
  212. default: false,
  213. },
  214. textRotation: {
  215. 0: 0,
  216. 1: 45,
  217. 2: -45,
  218. 3: "vertical",
  219. 4: 90,
  220. 5: -90,
  221. default: 0,
  222. },
  223. };
  224. let alignment = {
  225. vertical: luckyToExcel.vertical[vt],
  226. horizontal: luckyToExcel.horizontal[ht],
  227. wrapText: luckyToExcel.wrapText[tb],
  228. textRotation: luckyToExcel.textRotation[tr],
  229. };
  230. return alignment;
  231. };
  232. var borderConvert = function (borderType, style = 1, color = "#000") {
  233. // 对应luckysheet的config中borderinfo的的参数
  234. if (!borderType) {
  235. return {};
  236. }
  237. const luckyToExcel = {
  238. type: {
  239. "border-all": "all",
  240. "border-top": "top",
  241. "border-right": "right",
  242. "border-bottom": "bottom",
  243. "border-left": "left",
  244. },
  245. style: {
  246. 0: "none",
  247. 1: "thin",
  248. 2: "hair",
  249. 3: "dotted",
  250. 4: "dashDot", // 'Dashed',
  251. 5: "dashDot",
  252. 6: "dashDotDot",
  253. 7: "double",
  254. 8: "medium",
  255. 9: "mediumDashed",
  256. 10: "mediumDashDot",
  257. 11: "mediumDashDotDot",
  258. 12: "slantDashDot",
  259. 13: "thick",
  260. },
  261. };
  262. let template = {
  263. style: luckyToExcel.style[style],
  264. color: { argb: color.replace("#", "") },
  265. };
  266. let border = {};
  267. if (luckyToExcel.type[borderType] === "all") {
  268. border["top"] = template;
  269. border["right"] = template;
  270. border["bottom"] = template;
  271. border["left"] = template;
  272. } else {
  273. border[luckyToExcel.type[borderType]] = template;
  274. }
  275. // console.log('border', border)
  276. return border;
  277. };
  278. function addborderToCell(borders) {
  279. let border = {};
  280. const luckyExcel = {
  281. type: {
  282. l: "left",
  283. r: "right",
  284. b: "bottom",
  285. t: "top",
  286. },
  287. style: {
  288. 0: "none",
  289. 1: "thin",
  290. 2: "hair",
  291. 3: "dotted",
  292. 4: "dashDot", // 'Dashed',
  293. 5: "dashDot",
  294. 6: "dashDotDot",
  295. 7: "double",
  296. 8: "medium",
  297. 9: "mediumDashed",
  298. 10: "mediumDashDot",
  299. 11: "mediumDashDotDot",
  300. 12: "slantDashDot",
  301. 13: "thick",
  302. },
  303. };
  304. for (const bor in borders) {
  305. if (borders[bor]) {
  306. if (borders[bor].color.indexOf("rgb") === -1) {
  307. border[luckyExcel.type[bor]] = {
  308. style: luckyExcel.style[borders[bor].style],
  309. color: { argb: borders[bor].color.replace("#", "") },
  310. };
  311. } else {
  312. border[luckyExcel.type[bor]] = {
  313. style: luckyExcel.style[borders[bor].style],
  314. color: { argb: borders[bor].color },
  315. };
  316. }
  317. } else {
  318. border[luckyExcel.type[bor]] = {
  319. color: "#000000",
  320. style: 1,
  321. };
  322. }
  323. }
  324. return border;
  325. }
  326. function createCellPos(n) {
  327. let ordA = "A".charCodeAt(0);
  328. let ordZ = "Z".charCodeAt(0);
  329. let len = ordZ - ordA + 1;
  330. let s = "";
  331. while (n >= 0) {
  332. s = String.fromCharCode((n % len) + ordA) + s;
  333. n = Math.floor(n / len) - 1;
  334. }
  335. return s;
  336. }