web导出图片到excel表格

687 阅读3分钟

前端web页面如何把图片导出到excel

因为项目中遇到过一个需求,需要把图片资源导入到excel表格,我们项目用的是xlsx.js,没有能导出图片的api,所以想了个能不依赖服务端下,自己把图片导出到excel

图片资源是什么样的形式

我们存是url地址,只要你在页面的web中能显示图片,就代表能导出。base64不确定

主要原理

  1. 把html的table导入excel

  2. 如果是图片,每个单元格里加上img标签,自动导出为图片

  3. 使用特定的标签头。meta的协议,html的参数值等

    html标签的一些参数值
    xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"
    
代码,先写一个html页面,在web中显示。
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>导出图片和数据到Excel</title>
</head>

<body>
    <button id="btn">导出图片</button>
</body>
<script src="./lib/export2Excel.js"></script>
<script>

    // tHeader和tbody的数据需要一一对应
    let tHeader = ['鲜花', '颜色', '图片']
    let tbody = [
        {
            name: '菊花',
            color: '黄色',
            pic: 'https://ts1.cn.mm.bing.net/th/id/R-C.41c31182ed74babeba2f3b26a0b0f7d3?rik=%2bj9ZYlAspvGJDQ&riu=http%3a%2f%2fpic1.huashichang.com%2f2017%2f0716%2f21%2f596b6bda9b4ed.jpg&ehk=qBge7cVXDh%2b39lIopVsOiGhKgQ5CZuFos7qJItQ1zzM%3d&risl=&pid=ImgRaw&r=0'
        },
        {
            name: '月季花',
            color: '黄色',
            pic: 'https://img.huabaike.com/tukuimgs/442/20200922162822_702235.jpg'
        },
        {
            name: '玫瑰花',
            color: '红色',
            pic: 'https://tse1-mm.cn.bing.net/th/id/OIP-C.PJzyLc8c7jJk0Q8knhn2PQHaFy?w=244&h=191&c=7&r=0&o=5&dpr=1.3&pid=1.7'
        },

    ]
    const export2Excel = (theadData, tbodyData, dataname) => {
        let re = /http/ // 字符串中包含http,则默认为图片地址
        let th_len = theadData.length // 表头的长度
        let tb_len = tbodyData.length // 记录条数
        let width = 60 // 设置图片大小
        let height = 60

        // 添加表头信息
        let thead = '<thead><tr>'
        for (let i = 0; i < th_len; i++) {
            thead += '<th>' + theadData[i] + '</th>'
        }
        thead += '</tr></thead>'

        // 添加每一行数据
        let tbody = '<tbody>'
        for (let i = 0; i < tb_len; i++) {
            tbody += '<tr>'
            let row = tbodyData[i] // 获取每一行数据

            for (let key in row) {
                if (re.test(row[key])) {
                    // 如果为图片,则需要加div包住图片
                    tbody +=
                        '<td style="width:' +
                        width +
                        'px; height:' +
                        height +
                        'px; text-align: center; vertical-align: middle"><div style="display:inline"><img src=\'' +
                        row[key] +
                        "' " +
                        ' ' +
                        'width=' +
                        '"' +
                        width +
                        '"' +
                        ' ' +
                        'height=' +
                        '"' +
                        height +
                        '"' +
                        '></div></td>'
                } else {
                    tbody += '<td style="text-align:center">' + row[key] + '</td>'
                }
            }
            tbody += '</tr>'
        }
        tbody += '</tbody>'

        let table = thead + tbody

        // 导出表格
        exportToExcel(table, dataname)
    }



    document.getElementById('btn').addEventListener('click', function () {
        export2Excel(tHeader, tbody, '表格数据')

    })
</script>

</html>
引用的插件,只有几十行代码
/* eslint-disable */
let idTmr;
const getExplorer = () => {
  let explorer = window.navigator.userAgent;
  //ie
  if (explorer.indexOf("MSIE") >= 0) {
    return "ie";
  }
  //firefox
  else if (explorer.indexOf("Firefox") >= 0) {
    return "Firefox";
  }
  //Chrome
  else if (explorer.indexOf("Chrome") >= 0) {
    return "Chrome";
  }
  //Opera
  else if (explorer.indexOf("Opera") >= 0) {
    return "Opera";
  }
  //Safari
  else if (explorer.indexOf("Safari") >= 0) {
    return "Safari";
  }
};
// 判断浏览器是否为IE
const exportToExcel = (data, name) => {
  // 判断是否为IE
  if (getExplorer() == "ie") {
    tableToIE(data, name);
  } else {
    tableToNotIE(data, name);
  }
};

const Cleanup = () => {
  window.clearInterval(idTmr);
};

// ie浏览器下执行
const tableToIE = (data, name) => {
  let curTbl = data;
  let oXL = new ActiveXObject("Excel.Application");

  //创建AX对象excel
  let oWB = oXL.Workbooks.Add();
  //获取workbook对象
  let xlsheet = oWB.Worksheets(1);
  //激活当前sheet
  let sel = document.body.createTextRange();
  sel.moveToElementText(curTbl);
  //把表格中的内容移到TextRange中
  sel.select;
  //全选TextRange中内容
  sel.execCommand("Copy");
  //复制TextRange中内容
  xlsheet.Paste();
  //粘贴到活动的EXCEL中

  oXL.Visible = true;
  //设置excel可见属性

  try {
    let fname = oXL.Application.GetSaveAsFilename(
      "Excel.xls",
      "Excel Spreadsheets (*.xls), *.xls"
    );
  } catch (e) {
    print("Nested catch caught " + e);
  } finally {
    oWB.SaveAs(fname);

    oWB.Close((savechanges = false));
    //xls.visible = false;
    oXL.Quit();
    oXL = null;
    // 结束excel进程,退出完成
    window.setInterval("Cleanup();", 1);
    idTmr = window.setInterval("Cleanup();", 1);
  }
};

// 非ie浏览器下执行
const tableToNotIE = (function () {
  // 编码要用utf-8不然默认gbk会出现中文乱码
  let uri = "data:application/vnd.ms-excel;base64,",
    template =
      '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta charset="UTF-8"><!--[if gte mso 9]><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><![endif]--></head><body><table>{table}</table></body></html>',
    base64 = function (s) {
      return window.btoa(unescape(encodeURIComponent(s)));
    },
    format = (s, c) => {
      return s.replace(/{(\w+)}/g, (m, p) => {
        return c[p];
      });
    };
  return (table, name) => {
    let ctx = {
      worksheet: name,
      table,
    };

    //创建下载
    let link = document.createElement("a");
    link.setAttribute("href", uri + base64(format(template, ctx)));

    link.setAttribute("download", name);

    // window.location.href = uri + base64(format(template, ctx))
    link.click();
  };
})();

使用步骤:
  1. 现在web页面显示一个table表格,符合w3c标准的就行。
  2. 引入exprtTable2Excel这个代码,他的核心就是把table元素,转换成字符串。然后通过类似于xml存储数据的方式,导出到excel表格。
  3. 最后导出的图片在excel表,就能看到一模一样的数据
效果图

图片转存失败,建议将图片保存下来直接上传

OYOalUOA.png (785×823) (imgtp.com)

![图片转存失败,建议将图片保存下来直接上传](OYOalUOA.png (785×823) (imgtp.com))

使用优缺点
  1. 目前这种方式是的确可以导出图片,并且不需要依赖服务端同学,也不需要依赖其它大的插件库,比如sheetjs/xlsx.js等,轻巧灵活。
  2. 缺点也有,就是导出的图片并没有嵌入到单元格,而是浮在上面。
  3. 只能导出一张图片到单元格
  4. 导出的excel格式为.xls,而不是.xlsx。这个也可以改,就是改html标签的参数。
  5. 有些文本数据处理,会自动把一个单元格分割成多行。