Vue3+vite completes the front-end download of excel files/templates and specifies the cell size (pure front-end)

First of all, of course, download the relevant npm package

npm install --save file-save xlsx
npm install --save script-loader

Then I created a folder under utils to store this part of the function

 Then the next thing is the code

//excel.js

import { export_json_to_excel } from './Export2Excel'
export function downloadFile (url) {
  try {
    var elemIF = document.createElement('iframe')
    elemIF.src = url
    elemIF.style.display = 'none'
    document.body.appendChild(elemIF)
  } catch (e) {
    console.error(e)
  }
}
// 导出excel 表格  tabHeader 表头  tabFilterVal 过滤的字段  tabList 数据集合 
export function exportExcels (tabHeader, tabFilterVal, tabList, fileName = Math.random() * 100) {
  const data = formatJson(tabFilterVal, tabList)
  export_json_to_excel({
    header: tabHeader,
    data,
    filename: fileName
  })
  function formatJson (filterVal, tableData) {
    return tableData.map(v => {
      return filterVal.map(j => {
        return v[j]
      })
    })
  }
}

To modify the cell, you need to modify the code of Export2Excel.js, which is written in the remarks 

//Export2Excel.js

/* eslint-disable */
import {saveAs} from 'file-saver'
import {SSF,utils,write} from 'xlsx'

function generateArray (table) {
  var out = [];
  var rows = table.querySelectorAll('tr');
  var ranges = [];
  for (var R = 0; R < rows.length; ++R) {
    var outRow = [];
    var row = rows[R];
    var columns = row.querySelectorAll('td');
    for (var C = 0; C < columns.length; ++C) {
      var cell = columns[C];
      var colspan = cell.getAttribute('colspan');
      var rowspan = cell.getAttribute('rowspan');
      var cellValue = cell.innerText;
      if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;

      //Skip ranges
      ranges.forEach(function (range) {
        if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
          for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
        }
      });

      //Handle Row Span
      if (rowspan || colspan) {
        rowspan = rowspan || 1;
        colspan = colspan || 1;
        ranges.push({
          s: {
            r: R,
            c: outRow.length
          },
          e: {
            r: R + rowspan - 1,
            c: outRow.length + colspan - 1
          }
        });
      };

      //Handle Value
      outRow.push(cellValue !== "" ? cellValue : null);

      //Handle Colspan
      if (colspan)
        for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
    }
    out.push(outRow);
  }
  return [out, ranges];
};

function datenum (v, date1904) {
  if (date1904) v += 1462;
  var epoch = Date.parse(v);
  return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}

function sheet_from_array_of_arrays (data, opts) {
  var ws = {};
  var range = {
    s: {
      c: 10000000,
      r: 10000000
    },
    e: {
      c: 0,
      r: 0
    }
  };
  for (var R = 0; R != data.length; ++R) {
    for (var C = 0; C != data[R].length; ++C) {
      if (range.s.r > R) range.s.r = R;
      if (range.s.c > C) range.s.c = C;
      if (range.e.r < R) range.e.r = R;
      if (range.e.c < C) range.e.c = C;
      var cell = {
        v: data[R][C]
      };
      if (cell.v == null) continue;
      var cell_ref = utils.encode_cell({
        c: C,
        r: R
      });

      if (typeof cell.v === 'number') cell.t = 'n';
      else if (typeof cell.v === 'boolean') cell.t = 'b';
      else if (cell.v instanceof Date) {
        cell.t = 'n';
        cell.z = SSF._table[14];
        cell.v = datenum(cell.v);
      } else cell.t = 's';

      ws[cell_ref] = cell;
    }
  }
  if (range.s.c < 10000000) ws['!ref'] = utils.encode_range(range);
  return ws;
}

function Workbook () {
  if (!(this instanceof Workbook)) return new Workbook();
  this.SheetNames = [];
  this.Sheets = {};
}

function s2ab (s) {
  var buf = new ArrayBuffer(s.length);
  var view = new Uint8Array(buf);
  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
  return buf;
}

export function export_table_to_excel (id) {
  var theTable = document.getElementById(id);
  var oo = generateArray(theTable);
  var ranges = oo[1];

  /* original data */
  var data = oo[0];
  var ws_name = "SheetJS";

  var wb = new Workbook(),
    ws = sheet_from_array_of_arrays(data);

  /* add ranges to worksheet */
  // ws['!cols'] = ['apple', 'banan'];
  ws['!merges'] = ranges;

  /* add worksheet to workbook */
  wb.SheetNames.push(ws_name);
  wb.Sheets[ws_name] = ws;

  var wbout = write(wb, {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary'
  });

  saveAs(new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
  }), "test.xlsx")
}

export function export_json_to_excel ({
                                        header,
                                        data,
                                        filename,
                                        autoWidth = true,
                                        bookType = 'xlsx'
                                      } = {}) {
  /* original data */
  filename = filename || 'excel-list'
  data = [...data]
  data.unshift(header);
  var ws_name = "SheetJS";
  var wb = new Workbook(),
    ws = sheet_from_array_of_arrays(data);

  if (autoWidth) {
    /*设置worksheet每列的最大宽度*/
    const colWidth = data.map(row => row.map(val => {
      /*val值为你设置的表头也就是你的tagHeader*/
      /*先判断是否为null/undefined*/
      if (val == null) {
        return {
      /*如果为空单元格的宽度就是10*/
          'wch': 10
        };
      }
      /*再判断是否为中文*/
      else if (val.toString().charCodeAt(0) > 255) {
        return {
      /*如果你的表头为中文,单元格宽度就是你字符串长度的两倍*/
      /*如果你的表头为中文就可以设置这里wch的值*/
          'wch': val.toString().length * 2
        };
      } else {
        return {
      /*如果你的表头为英文,单元格宽度就是你字符串长度*/
      /*如果你的表头为英文就可以设置这里wch的值*/
          'wch': val.toString().length
        };
      }
    }))
    /*以第一行为初始值*/
    let result = colWidth[0];
    for (let i = 1; i < colWidth.length; i++) {
      for (let j = 0; j < colWidth[i].length; j++) {
        if (result[j]['wch'] < colWidth[i][j]['wch']) {
          result[j]['wch'] = colWidth[i][j]['wch'];
        }
      }
    }
    ws['!cols'] = result;
  }

  /* add worksheet to workbook */
  wb.SheetNames.push(ws_name);
  wb.Sheets[ws_name] = ws;

  var wbout = write(wb, {
    bookType: bookType,
    bookSST: false,
    type: 'binary'
  });
  saveAs(new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
  }), `${filename}.${bookType}`);
}
//导出的excel数据  如果只想要模板不想里面有数据可以不创建此文件或者导出的数据字段都为空也行

//模板数据
export const templateData = [
  {
    name:'',
    jobNumber:'',
    phone:'',
    email:'',
  }
]

 Then introduce related methods on the page where you want to write this function

import { exportExcels } from '@/utils/excelTemplate/excel'
import {templateData} from '@/utils/excelTemplate/templateData'

 After the import is complete, it is ok to bind your event directly on your page. If you want to have data in it, you can change the third parameter of the exportExcels method to the data of the imported templateData. I just want to You want a template, so it's useless, it's just an empty array

const downExcelTemplate = () => {
  const tagHeader = ['员工名称', '员工工号', '手机号', '邮箱']
  const tagFilterVal = ['name', 'jobNumber', 'phone', 'email']
  exportExcels(tagHeader,tagFilterVal,[],'员工表')
}

This is the end. I searched a lot of methods on the Internet and I don’t know why the error was reported. I feel that it may be because of the vue3 I used. Then I took some and changed it myself. It’s ok

This is the final rendering

Guess you like

Origin blog.csdn.net/LMCyyds/article/details/131086567