exp2File.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import * as XLSX from 'xlsx'
  2. /**
  3. * 解析后的浮点数转时间戳
  4. * @param num 时间浮点
  5. */
  6. const number2times = (num: number) => {
  7. const utc_value = (num - 25569) * 86400
  8. const date_info = new Date(utc_value * 1000).getTime()
  9. const newtime = (date_info - 8 * 3600 * 1000)
  10. return newtime
  11. }
  12. /**
  13. * 自动下载
  14. * @param url 保存地址|blob
  15. * @param saveName 文件名
  16. */
  17. const openDownloadDialog = (url: any, saveName: string) => {
  18. if (typeof url === 'object' && url instanceof Blob) {
  19. url = URL.createObjectURL(url) // 创建blob地址
  20. }
  21. const aLink = document.createElement('a')
  22. aLink.href = url
  23. aLink.download = saveName || '' // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
  24. let event
  25. if (window.MouseEvent) event = new MouseEvent('click')
  26. else {
  27. event = document.createEvent('MouseEvents')
  28. event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
  29. }
  30. aLink.dispatchEvent(event)
  31. }
  32. /**
  33. * 解析excel表格
  34. * @param file 文件
  35. * @returns
  36. */
  37. export const exp2json = async (file: File) => {
  38. return await new Promise((resolve, reject) => {
  39. try {
  40. const reader = new FileReader()
  41. reader.onload = (e: any) => {
  42. const wb = XLSX.read(e.target.result, {
  43. type: 'binary'
  44. }) // 读取完成的数据
  45. // 转成json header解析第一行标题
  46. const data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { header: 1 })
  47. resolve(data)
  48. }
  49. reader.readAsBinaryString(file)
  50. } catch (error) {
  51. console.log('解析错误')
  52. reject(error)
  53. }
  54. })
  55. }
  56. /**
  57. * 导出excel表格
  58. * @param arr 数据是数组包含的对象
  59. * @param fileName 名字
  60. */
  61. export const exp2excel = (arr: Array<any>, fileName:string,cellMerges?:Array<any>) => {
  62. const sheet = XLSX.utils.json_to_sheet(arr);
  63. // excel宽高设置
  64. sheet["!cols"] = arr.map(() => {
  65. return { wch: 30 }
  66. })
  67. if(cellMerges){
  68. sheet['!merges'] = cellMerges; // <====合并单元格
  69. }
  70. // 转blob
  71. const sheet2blob = (sheet: any, sheetName='sheet1') => {
  72. const workbook = {
  73. SheetNames: [sheetName],
  74. Sheets: {} as any
  75. };
  76. workbook.Sheets[sheetName] = sheet;
  77. // 生成excel的配置项
  78. const wopts = {
  79. bookType: 'xlsx', // 要生成的文件类型
  80. bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
  81. type: 'binary'
  82. } as any
  83. const wbout = XLSX.write(workbook, wopts);
  84. // 字符串转ArrayBuffer
  85. const s2ab = (s: string) => {
  86. let buf = new ArrayBuffer(s.length);
  87. let view = new Uint8Array(buf);
  88. for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
  89. return buf;
  90. }
  91. const blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
  92. return blob;
  93. }
  94. openDownloadDialog(sheet2blob(sheet), fileName + '.xlsx')
  95. }
  96. /**
  97. * dom导出excel
  98. * @param domID domID
  99. * @param fileName 文件名
  100. */
  101. export const dom2excel = (domID: string, fileName: string) => {
  102. const dom = document.getElementsByTagName(domID)
  103. if (!dom) return
  104. const wb = XLSX.utils.table_to_book(dom[0])
  105. const baty = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' })
  106. // 字符串转ArrayBuffer
  107. const s2ab = (s: any) => {
  108. const buf = new ArrayBuffer(s.length)
  109. const view = new Uint8Array(buf)
  110. for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
  111. return buf
  112. }
  113. const blob = new Blob([s2ab(baty)], { type: 'application/octet-stream' })
  114. openDownloadDialog(blob, fileName + '.xlsx')
  115. }
  116. /**
  117. * 数组按指定key值分组
  118. * @param {*} array
  119. * @param {*} id
  120. * @returns
  121. */
  122. export function groupBy(array:Array<any>, id:string) {
  123. let groups = {} as any;
  124. array.forEach((o) => {
  125. let group = JSON.stringify(o[id]);
  126. if (typeof o[id] === 'string') {
  127. group = o[id]
  128. }
  129. groups[group] = groups[group] || [];
  130. groups[group].push(o);
  131. });
  132. // return Object.values(groups);
  133. return groups;
  134. }