当前位置: 首页 > 工具软件 > ExcelJS > 使用案例 >

nodejs使用exceljs批量导出图片到excel并将excel下载到本地

龙珂
2023-12-01

由于img.onload方法不同于其他函数,他是一个事件回调。
js是单线程的 他会先按照顺序执行主程序 当主程序执行完成后才会执行事件回调 所以在批量导出图片时onload事件总是最后执行
采用了很多办法 ,网上提供的所有解决办法我都试过了,没有能解决的。所以我将解决方法转到后端来实现,但是node.js默认是单线程,一个node.js应用无法利用多核资源,将网络图片转成base64后再利用exceljs库写到excel中单张图片就需要一秒多的时间,所以最终采用定时器来解决,最近比较忙,就不详细阐述了,代码放下面:
js代码如下:

       function main(data, sign, l) {
                var timer = setInterval(function () {
                    var url = data[sign].asin_img;
                    var img = new Image();
                    img.src = url;
                    img.crossOrigin = "*";
                    if (img.complete == true) {
                        var base64 = getBase64Image(img);
                        data[sign].img = base64;
                        sign++;
                        computedLong(sign, l)
                        if (sign >= l) {
                            clearInterval(timer);
                            uploadBase(data)
                        }
                    }
                }, 100)
          }
          function getBase64Image(img) {//根据网络图片的地址将图片转为base64 nodejs exceljs库需要 如不明白为什么 可以去看一下exceljs的官方文档
                var canvas = document.createElement("canvas");
                canvas.width = img.width;
                canvas.height = img.height;
                var ctx = canvas.getContext("2d");
                ctx.drawImage(img, 0, 0, img.width, img.height);
                var dataURL = canvas.toDataURL("image/jpeg");  // 可选其他值 image/jpeg
                return dataURL;
            }

            function uploadBase(data) {
                var fileName = getNowFormatDate(time).replace(/\s+/g, "") + (Math.random() * 999).toFixed(0);
                $.ajax({
                    type: "post",
                    url: "",
                    data: {
                        baseData: JSON.stringify(data),
                        fileName
                    },
                    success: function (data) {
                        if (data.code === 0) {
                            layer.msg(data.msg)
                            var a = document.createElement('a');
                            a.setAttribute('href', "/node_amz/data/" + fileName + ".xlsx");
                            document.body.appendChild(a);
                            a.click();//导出完成后 自动下载excel表格到本地
                            $(".loader-dialog").hide();
                        } else {
                            alert("接口异常")
                        }
                    },
                    error: function (err) {
                        alert("服务异常")
                    }
                })
            }
           $("#out").click(function () {
                var startTime = $("#startTime").val();
                var endTime = $("#endTime").val();
                var datas = [];
                //查询接口
                $.ajax({
                    type: "get",
                    url: "",
                    success: function (data) {
                        $(".loader-dialog").show();
                        data = JSON.parse(data);
                        if (data.return_code === 0) {
                            var prod_info = data.prod_info;
                            for (var i = 0; i < prod_info.length; i++) {
                                var asin_info = prod_info[i].asin_info;
                                for (let j = 0; j < asin_info.length; j++) {
                                    datas.push(asin_info[j])
                                    sessionStorage.setItem("sessionBase", JSON.stringify(datas))
                                }
                            }
                            var sessionBaseData = JSON.parse(sessionStorage.getItem("sessionBase"));
                            var l = sessionBaseData.length;//导出图片的数量 控制递归函数的执行次数 比较重要
                            $(".proBefore").text(0)
                            $(".proAfter").text(l)
                            main(sessionBaseData, 0, l)//执行
                        } else {
                            alert("接口异常")
                        }
                    },
                    error: function (err) {
                        alert("获取sku异常")
                    }
                })
            })

nodejs代码如下:(将代码放到index.js文件)

var express = require("express");
var router = express.Router();
const fs = require("fs");
const Excel = require("exceljs");
var http = require("https");
router.post("/", function (req, res) {
  const workbook = new Excel.Workbook();
  workbook.created = new Date();
  workbook.modified = new Date();
  let sheet = workbook.addWorksheet("excel文件名称", {
    properties: { defaultRowHeight: 80 },
  });

  sheet.columns = [
    { header: "id", key: "sku_id", width: 15 },
    { header: "asin", key: "asin", width: 15 },
    { header: "asin_name", key: "asin_name", width: 15 },
    { header: "sku缩略图", key: "sku_img", width: 25 },
  ];
  res.header("Access-Control-Allow-Origin", "*");
  var body = req.body.baseData;
  var fileName = req.body.fileName;
  baseDatas = JSON.parse(body);
  sheet.addRows(baseDatas);
  function addImg() {
    return new Promise((resolve, reject) => {
      sheet.eachRow(function (row, rowNumber) {
        let rows = sheet.getRow(rowNumber + 1);
        rows.height = 80;
        rows.eachCell(function (cell, colNumber) {
          rows.getCell(colNumber).alignment = {
            vertical: "middle",
            horizontal: "center",
            wrapText: true,
          };
        });
      });
      for (var i = 0; i < baseDatas.length; i++) {
        var imageId = workbook.addImage({
          base64: baseDatas[i].img,
          extension: "jpeg",
        });
        sheet.addImage(imageId, {
          tl: { col: 3.5, row: i + 1 + 0.5 },
          ext: { width: 80, height: 80 },
        });
        if (i === baseDatas.length - 1) {
          resolve();
        }
      }
    });
  }

  addImg().then(() => {
    var s = "./" + fileName + ".xlsx";
    workbook.xlsx.writeFile(s).then(
      () => {
        res.send({
          code: 0,
          msg: "导出成功",
        });
      },
      (err) => {
        res.send({
          code: -1,
          msg: "请联系管理员",
        });
      }
    );
  });
});
module.exports = router;

里面涉及到的exceljs库的知识直接去官网看一下,链接放这exceljs官网 如果对你有所帮助,记得点个赞哦!

 类似资料: