zoukankan      html  css  js  c++  java
  • 前端 vue/react 或者 js 导入/导出 xlsx/xls (带样式)表格的功能

    第一种
    导出表格的功能:

    yarn add xlsx script-loader file-saver xlsx-style

    效果展示

    xlsx-style的bug修复:node_module/xlsx-style/dist/cpexcel.js的807行的var cpt = require('./cpt' + 'able')改为var cpt = cptable;

    上封装的代码:

    require('script-loader!file-saver');
    import XLSX from 'xlsx-style';
    import XLSX2 from 'xlsx';
    
    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 = XLSX.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 = XLSX.SSF._table[14];
    cell.v = datenum(cell.v);
    } else cell.t = 's';
    
    ws[cell_ref] = cell;
    }
    }
    if (range.s.c < 10000000) ws['!ref'] = XLSX.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;
    }
    
    // 通过table标签渲染导出表格
    export function export_table_to_excel({
    id,
    filename,
    bookType = 'xlsx',
    styleFun
    } = {}) {
    var table = document.querySelector(id);
    var ws = XLSX2.utils.table_to_sheet(table);
    styleFun(ws);
    var wb = XLSX2.utils.book_new();
    XLSX2.utils.book_append_sheet(wb, ws, "SheetJS");
    var wbout = XLSX.write(wb, {
    bookType: bookType,
    bookSST: false,
    type: 'binary'
    });
    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;
    }
    saveAs(new Blob([s2ab(wbout)], { type: "" }), filename + "." + bookType)
    }
    
    //通过json渲染导出表格
    export function export_json_to_excel({
    multiHeader = [],
    header,
    data,
    filename,
    merges = [],
    autoWidth = true,
    bookType = 'xlsx'
    } = {}) {
    /* original data */
    filename = filename || 'excel-list'
    data = [...data]
    data.unshift(header);
    
    for (let i = multiHeader.length - 1; i > -1; i--) {
    data.unshift(multiHeader[i])
    }
    
    var ws_name = "SheetJS";
    var wb = new Workbook(),
    ws = sheet_from_array_of_arrays(data);
    
    if (merges.length > 0) {
    if (!ws['!merges']) ws['!merges'] = [];
    merges.forEach(item => {
    ws['!merges'].push(XLSX.utils.decode_range(item))
    })
    }
    
    if (autoWidth) {
    /*设置worksheet每列的最大宽度*/
    const colWidth = data.map(row => row.map(val => {
    /*先判断是否为null/undefined*/
    if (val == null) {
    return {
    'wch': 10
    };
    }
    /*再判断是否为中文*/
    else if (val.toString().charCodeAt(0) > 255) {
    return {
    'wch': val.toString().length * 2
    };
    } else {
    return {
    '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 = XLSX.write(wb, {
    bookType: bookType,
    bookSST: false,
    type: 'binary'
    });
    saveAs(new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
    }), `${filename}.${bookType}`);
    }


    提供了2种调用方式:

    1.直接获取table标签获取

    exportTable() {
    //通过table标签渲染导出表格
    import("@/vendor/Export2Excel").then(excel => {
    excel.export_table_to_excel({
    id: this.id,
    filename: this.filename,
    bookType: this.bookType,
    styleFun: function(ws) { // 自定义样式
    for (let item in ws) {
    switch (item) {
    case "!merges":
    break;
    case "!ref":
    break;
    case "A1":
    ws['A1'].s = {
    font: {
    sz: 13,
    bold: true,
    color: {
    rgb: "FFFFAA00"
    }
    },
    alignment: {
    horizontal: "center",
    vertical: "center"
    }
    };
    break;
    default:
    ws[item].s = {
    font: {
    sz: 13,
    bold: true,
    },
    alignment: {
    horizontal: "center",
    vertical: "center"
    }
    };
    }
    }
    }
    });
    });
    },


    2.通过后台数据data数组

    exportTable() {
    import("@/vendor/Export2Excel").then(excel => {
    const multiHeader = [
    [
    "工作情况一览表",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    ""
    ],
    [
    "截止日期:2019年09月11日",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    ""
    ]
    ];
    const tHeader = [
    "序号",
    "分类",
    "报建项目",
    "有效期",
    "计划开始时间",
    "计划完成时间",
    "受理",
    "所需资料",
    "办理周期",
    "责任人",
    "工作进展"
    ];
    const filterVal = [
    "code",
    "name",
    "orderBy",
    "pageviews",
    "display_time"
    ];
    const list = this.tableData;
    const data = this.formatJson(filterVal, list);
    const merges = ['A1:K1','A2:K2']; // 合并单元格
    excel.export_json_to_excel({
    multiHeader,
    header: tHeader,
    merges,
    data,
    filename: this.filename,
    autoWidth: this.autoWidth,
    bookType: this.bookType
    });
    });
    },
    // 辅助导出表格的函数
    formatJson(filterVal, jsonData) {
    return jsonData.map(v =>
    filterVal.map(j => {
    if (j === "timestamp") {
    return parseTime(v[j]);
    } else {
    return v[j];
    }
    })
    );
    },


    对应的html就是element的table

    <div id="protable">
    <el-table :data="tableData" :span-method="objectSpanMethod" border style=" 100%; margin-top: 20px">
    <el-table-column label="工作情况一览表" align="center">
    <el-table-column label="截止日期:2019年09月11日" align="right">
    <el-table-column prop="id" label="序号" align="center">
    </el-table-column>
    <el-table-column prop="code" label="分类" align="center">
    </el-table-column>
    <el-table-column prop="name" label="报建项目" align="center">
    </el-table-column>
    <el-table-column prop="amount2" label="有效期" align="center">
    </el-table-column>
    <el-table-column prop="amount3" label="计划开始时间" align="center">
    </el-table-column>
    <el-table-column prop="amount3" label="计划完成时间" align="center">
    </el-table-column>
    <el-table-column prop="amount3" label="受理" align="center">
    </el-table-column>
    <el-table-column prop="amount3" label="所需资料" align="center">
    </el-table-column>
    <el-table-column prop="amount3" label="办理周期" align="center">
    </el-table-column>
    <el-table-column prop="amount3" label="责任人" align="center">
    </el-table-column>
    <el-table-column prop="amount3" label="工作进展概述" align="center">
    </el-table-column>
    </el-table-column>
    </el-table-column>
    </el-table>
    </div>

    第二种

    1.新建exportExcel.js文件并填入以下代码
    // 导出Excel方法(表格id,不加扩展名的文件名,sheet名)
    export function exportExcelMethod(tableId, fileName, sheetName) {
    tableToExcel(tableId, fileName, sheetName)
    }
    const tableToExcel = (function() {
    const uri = 'data:application/vnd.ms-excel;base64,'
    // 设置导出表格的单元格默认高度/宽度/边框样式/字体颜色/背景颜色/居中,网页显示表格宽度建议1240,tr/td视情况而定
    const template = `<html xmlns:x="urn:schemas-microsoft-com:office:excel"><head><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><meta charset="UTF-8"><style type="text/css">table td {border: 1px solid #000000;100px;text-align: center;color: #000000;} th {border: 1px solid #000000;100px;text-align: center;color: #000000;}</style></head><body><table>{table}</table></body></html>`
    const base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
    const format = function(s, c) { return s.replace(/{(w+)}/g, function(m, p) { return c[p] }) }
    return function(table, filename, sheetname) {
    if (!table.nodeType) table = document.getElementById(table)
    const ctx = { worksheet: sheetname || 'Worksheet', table: table.innerHTML }
    const aTag = document.createElement('a')
    aTag.href = uri + base64(format(template, ctx))
    aTag.download = filename
    aTag.click()
    }
    })()
    2.在需要导出EXCEL的页面上引入方法
     
    import { exportExcelMethod } from './exportExcel'
    3.将需要导出的表格元素定义一个id,我的table的id=“table”
     
    <table id="table" class="tg" style="table-layout: fixed;  1228px;margin: auto;left: 50%;right: 50%">
    <tr>
    <th style="background-color: red; height: 60px;" colspan="6">Header 1</th>
    </tr>
    <tr>
    <th style="background-color: red">Header 1</th>
    <th style="background-color: red">Header 1</th>
    <th style="background-color: red">Header 1</th>
    <th style="background-color: red">Header 1</th>
    <th style="background-color: red">Header 1</th>
    <th style="background-color: red">Header 1</th>
    </tr>
    <tr>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    </tr>
    <tr>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    </tr>
    <tr>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    </tr>
    <tr>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    </tr>
    </table>
    4.使用导出函数,填入三个参数,第一个为表格元素的id,第二个为导出的excel文件名,第三个为sheet表名
     
    exportExcelMethod('table', '发货单', 'sheet1')
  • 相关阅读:
    IIS负载均衡Application Request Route详解第二篇:创建与配置Server Farm
    负载均衡原理与实践详解 第一篇(重新整理)
    负载均衡原理剖析与实践第一篇介绍篇
    查询优化器内核剖析第八篇:执行引擎之数据访问操作Seek(上)
    提高ASP.NET性能与可伸缩性的几个个常用方法剖析
    IIS负载均衡Application Request Route详解第三篇:使用ARR进行Http请求的负载均衡(上)
    负载均衡第二篇负载均衡基础知识普及
    查询优化器内核剖析第七篇:执行引擎之数据访问操作Scan
    活在当下:人这一辈子,你总的坚持点什么
    LINQ 的演变及其对 C# 设计的影响
  • 原文地址:https://www.cnblogs.com/plBlog/p/11772314.html
Copyright © 2011-2022 走看看