• 导出Excel、PDF和下载图片


    创建时间: 2020-03-16;测试:chrome v80.0.3987.122 正常

    导出 Excel (利用xlsx)

    • 安装 xlsx 引入包 import XLSX from 'xlsx/dist/xlsx.mini.min.js';

    实现原理:将其描述表格的 JSON 按照电子表格的协议转换为为压缩的 zip 字符,再通过一系列方法将其转换为 Blob URL;(相关原理代码如下)

    function blobify(strData) {
        var buf = new ArrayBuffer(strData.length), view = new Uint8Array(buf);
        for (var i=0; i!=strData.length; ++i) view[i] = strData.charCodeAt(i) & 0xFF;
        return buf;
    }
    var excelBlob = new Blob([blobify(data)], {type:"application/octet-stream"});
    var blobURL=URL.createObjectURL(excelBlob);
    

    相关业务实现代码如下:

    exportData = () => {
        /**
         * @des 生成excel
         * @param { Array } data ([[name, score],['hew', 80]]) 
         * @param { String } name 表格名称
         */
        const fn = (data, name) => {
            name = name || 'table';
            /** 设置文件名以及格式, 默认xlsx */
            const filename = /./.test(name) ? name : `${name}.xlsx`;
            /** Excel第一个sheet的名称 */
            const wsName = 'sheet'; 
            const newBook = XLSX.utils.book_new();
            const ws = XLSX.utils.aoa_to_sheet(data);
            /** 将数据添加到工作薄 */
            XLSX.utils.book_append_sheet(newBook, ws, wsName);  
            XLSX.writeFile(newBook, filename);
        }
    
        fn([
            ['h1','h2','h3', 'h4'], 
            [1,2,3,4],
            [true, false, null, 5],
            [true, false, null, '中文'],
        ], '表格')
    }
    

    导出PDF

    • 引入 jspdf 和 html2canvas

    import * as jsPDF from 'jspdf'

    import html2canvas from 'html2canvas';
    html2canvas 原理是读取DOM,并根据规则在画布上绘制,但部分css样式是无法实现的

    • 主要代码
     html2canvas(document.querySelector('.need-pdf')).then((canvas) => {
        let canvasWidth = canvas.width
        let canvasHeight = canvas.height
        // a4纸的尺寸[595.28,841.89]
        let pageHeight = canvasWidth / 592.28 * 841.89
        let imgWidth = 595.28
        let imgHeight = 592.28 / canvasWidth * canvasHeight
        let pageData = canvas.toDataURL('image/jpeg', 1.0)
    
        let pdf = new jsPDF('', 'pt', 'a4')
        if (canvasHeight < pageHeight) {
            // 参数说明:图片数据,格式,距左边距,距上边距,图宽,图高,...(其它参数)  这里的单位都和上面创建pdf实例时一致
            pdf.addImage(pageData, 'JPEG', 20, 0, imgWidth, imgHeight)
        } else {
            // 分页操作,以下操作方式较为粗糙,分页处直接分割内容 
            let theRestHeight = canvasHeight;
            let y = 0;
            while (theRestHeight > 0) {
                // 原理是将同一张图放在不同页面,但上移不同的距离,实现分页
                pdf.addImage(pageData, 'JPEG', 0, y, imgWidth, imgHeight)
                theRestHeight -= pageHeight
                y -= 841.89
                if (theRestHeight > 0) {
                    pdf.addPage()
                }
            }
        }
        pdf.save('table.pdf')
    })
    

    下载图片

    • 利用 a 标签

    IE存在兼容问题,必须是同源图片(非同源会在新标签页打开),download属性值要跟图片格式

    <a href="xxx" alt="no" download="new-name.jpg">下载图片</a>
    
    • 如果是放 cdn 或是 图片服务器(服务器也要设置允许跨域)
    const canvasEle = document.createElement('canvas');
    const ctx = canvasEle.getContext('2d');
    
    const imgEle = new Image();
    imgEle.setAttribute('crossOrigin', 'anonymous'); 
    imgEle.onload = function() {
        canvasEle.width = this.width;
        canvasEle.height = this.height;
        ctx.drawImage(this, 0 , 0, this.width, this.height);
    
        const aEle = document.createElement('a');
        aEle.setAttribute('href', canvasEle.toDataURL('image/jpeg'));
        aEle.setAttribute('download', 'cross.jpg');
        aEle.click();
    }
    imgEle.src = 'xxx.jpg';
    
    • 利用 ajax 请求,要求也是同上,只是不需要兼容 crossOrigin
    function dl() {
        var xhr = new XMLHttpRequest();
        xhr.onload = function () {
            var url = URL.createObjectURL(this.response);
            var img = new Image();
            img.onload = function () {
                const aEle = document.createElement('a');
                aEle.setAttribute('href', canvasEle.toDataURL('image/jpeg'));
                aEle.setAttribute('download', 'cross.jpg');
                aEle.click();
                // 释放内存
                URL.revokeObjectURL(url);
            };
            img.src = url;
        };
        xhr.open('GET', url, true);
        xhr.responseType = 'blob';
        xhr.send();
    }
    

    欢迎交流 Github

  • 相关阅读:
    异常处理的讨论 CQ
    看看这个Lock可不可靠 CQ
    Smart Client Software Factory(SCSF) 之起步 CQ
    建设高性能网站
    关系数据库还是NoSQL数据库
    另类递归
    cacti监控redis状态
    NoSQL书籍大全
    如果判断function的调用者?
    Error while creating db diagram:Cannot insert NULL into column diagram_id
  • 原文地址:https://www.cnblogs.com/he-wei/p/12502827.html
Copyright © 2020-2023  润新知