node 实现导出, 在导出excel中包含图片(附件)

news2024/10/7 18:30:16

如果想查看 node mySql 实现数据的导入导出,以及导入批量插入的sql语句,连接如下

node mySql 实现数据的导入导出,以及导入批量插入的sql语句-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/snows_l/article/details/139998373

一、效果如图:

二、实现方法

利用里 exceljs 插件的 addImage 方法进行插入, 关键代码如下:

const workbook = new Excel.Workbook();
const worksheet = workbook.addWorksheet('收入明细');
// 设置表头
// worksheet.addRow(['标题', '月份', '收入金额', '备注', '收入截图']);
let baseTableTitle = [
  { header: '标题', key: 'title', width: 20 },
  { header: '月份', key: 'date', width: 12 },
  { header: '收入金额(元)', key: 'money', width: 16 },
  { header: '就职于', key: 'source', width: 12 },
  { header: '备注', key: 'remark', width: 24 }
];
if (includePic == 'true') {
  baseTableTitle.push({ header: '收入截图', key: 'pic', width: 16 });
}
worksheet.columns = baseTableTitle;

// 循环写入数据
data.forEach(async (item, index) => {
  const rowData = worksheet.addRow([item.title, item.date, item.money, item.sourceStr, item.remark]);
  // 指定行高
  rowData.height = 50;
});

// 插入图片
if (includePic == 'true') {
  for (let i = 0; i < data.length; i++) {
    // 插入图片到Excel
    const imageId = workbook.addImage({
      filename: '../public' + data[i].pic, // 图片路径 不能出现中文名字
      extension: 'jpeg'
    });
    // E代表第5列,i+2代表第i+2行,F${i+2}:F${i+2}代表第i+2行第6列
    worksheet.addImage(imageId, `F${i + 2}:F${i + 2}`);
  }
}

// buffer 返回给前端即可
const buffer = await workbook.xlsx.writeBuffer();

三、完整代码

/*
 * @Description: ------------ fileDescription -----------
 * @Author: snows_l snows_l@163.com
 * @Date: 2024-04-15 14:29:31
 * @LastEditors: snows_l snows_l@163.com
 * @LastEditTime: 2024-06-24 22:34:26
 * @FilePath: /Website/Server/src/router/wages.js
 */
const express = require('express');
const db = require('../../utils/connDB');
const router = express.Router();
const Excel = require('exceljs');


// 导出
router.get('/wages/export', async (req, res) => {
  let { eDate, sDate, source, includePic } = req.query;
  let sql = `SELECT * FROM wages`;
  if (eDate && sDate) {
    sql += ` WHERE date >= '${sDate}-01' AND date <= '${eDate}-28'`;
  }
  if (source) {
    sql += ` ${eDate && sDate ? 'AND' : 'WHERE'}  source = '${source}'`;
  }
  sql += ` ${(eDate && sDate) || source ? 'and' : 'where'} del_flag = ? ORDER BY date DESC`;
  const params = [0];
  try {
    db.queryAsync(sql, params).then(ress => {
      const data = ress.results;
      dictSql = `select* from sys_dict where dictType = 'wages_source' and pid <> 0 order by sort ASC;`;
      db.queryAsync(dictSql).then(async dictRes => {
        const dictData = dictRes.results;
        // 处理就职于字典
        data.forEach(item => {
          item.sourceStr = dictData.find(dict => dict.value === item.source).label;
        });
        /**
         * 使用 XLSX 库导出excel文件 支持普通的xlsx格式
         */
        // 将数据转换为工作表
        // const ws = XLSX.utils.json_to_sheet(data);
        // // 创建工作簿并添加工作表
        // const wb = XLSX.utils.book_new();
        // XLSX.utils.book_append_sheet(wb, ws, '收入');
        // //生成Excel文件的二进制数据
        // const excelBuffer = XLSX.write(wb, {
        //   type: 'buffer',
        //   bookType: 'xlsx'
        // });
        // const realName = encodeURI('收入报表.xlsx', 'GBK').toString('iso8859-1');
        // // 设置响应头
        // res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        // res.setHeader('Content-Disposition', 'attachment; filename=' + realName);
        // // 发送Excel文件
        // res.send(excelBuffer);

        /**
         * 使用 exceljs 库导出excel文件
         */
        // 下载图片并保存到临时文件
        // const downloadImage = async (url, filePath) => {
        //   const response = await axios.get(url, { responseType: 'arraybuffer' });
        //   fs.writeFileSync(filePath, response.data);
        // };

        const workbook = new Excel.Workbook();
        const worksheet = workbook.addWorksheet('收入明细');
        // 设置表头
        // worksheet.addRow(['标题', '月份', '收入金额', '备注', '收入截图']);
        let baseTableTitle = [
          { header: '标题', key: 'title', width: 20 },
          { header: '月份', key: 'date', width: 12 },
          { header: '收入金额(元)', key: 'money', width: 16 },
          { header: '就职于', key: 'source', width: 12 },
          { header: '备注', key: 'remark', width: 24 }
        ];
        if (includePic == 'true') {
          baseTableTitle.push({ header: '收入截图', key: 'pic', width: 16 });
        }

        worksheet.columns = baseTableTitle;
        // 循环写入数据
        data.forEach(async (item, index) => {
          const rowData = worksheet.addRow([item.title, item.date, item.money, item.sourceStr, item.remark]);
          // 指定行高
          rowData.height = 50;
        });

        // 插入图片
        if (includePic == 'true') {
          for (let i = 0; i < data.length; i++) {
            // 插入图片到Excel
            const imageId = workbook.addImage({
              filename: '../public' + data[i].pic, // 图片路径 不能出现中文名字
              extension: 'jpeg'
            });
            // E代表第5列,i+2代表第i+2行,F${i+2}:F${i+2}代表第i+2行第6列
            worksheet.addImage(imageId, `F${i + 2}:F${i + 2}`);
          }
        }

        const buffer = await workbook.xlsx.writeBuffer();
        // 处理中文文件名
        const realName = encodeURI('收入报表.xlsx', 'GBK').toString('iso8859-1');
        // 设置响应头
        res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        res.setHeader('Content-Disposition', 'attachment; filename=' + realName);
        // 发送Excel文件
        res.send(buffer);
      });
    });
  } catch (error) {
    return res.send({
      code: 500,
      data: null,
      msg: '导出失败'
    });
  }
});

module.exports = router;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1866030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计师进阶指南:掌握这6条版式设计要点

布局设计是设计师的必修课。优秀的排版不是强制性的“东拼西凑”&#xff0c;而是通过设计师独特的排版获得的。这不是简单的信息列表&#xff0c;而是认真思考如何分层、有节奏地组织和安排元素。今天我将给你带来它 6 文章还附带了布局设计模板资源&#xff0c;设计师朋友一定…

第三十三篇——互联网广告:为什么Google搜索的广告效果好?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 对于信息的利用&#xff0c;再广告这个维度中去洞察&#xff0c;你又能发…

PS系统教程30

图层蒙版组合使用 案例介绍 全选背景图-复制背景图粘贴背景图CtrlI反选背景色填充黑色快速选区工具框柱需要素材画笔涂抹白色 步骤截图 1-3 4-5 图层蒙版与渐变工具结合使用 案例2 注意 使用PS的渐变工具覆盖全部的原因可能包括操作不当或设置错误。 操作不当&#xff1…

【Qt】Qt多线程编程指南:提升应用性能与用户体验

文章目录 前言1. Qt 多线程概述2. QThread 常用 API3. 使用线程4. 多线的使用场景5. 线程安全问题5.1. 加锁5.2. QReadWriteLocker、QReadLocker、QWriteLocker 6. 条件变量 与 信号量6.1. 条件变量6.2 信号量 总结 前言 在现代软件开发中&#xff0c;多线程编程已成为一个不可…

越有水平的领导,越擅长用这3个字来管人,怪不得执行力强

越有水平的领导&#xff0c;越擅长用这3个字来管人&#xff0c;怪不得执行力强 第一个字&#xff1a;“实” 要想提高执行力&#xff0c;必须发扬务实、实干、刻苦勤勉的工作精神。纸上谈兵&#xff0c;夸夸其谈的事情少做&#xff0c;多行动&#xff0c;少说话。 沉浸在表面…

问界M9累计大定破10万,创中国豪车新纪录

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 6月26日消息&#xff0c;华为常务董事、终端BG董事长、智能汽车解决方案BU董事长余承东今日宣布&#xff0c;问界M9上市6个月&#xff0c;累计大定突破10万辆。 这一成绩&#xff0c;也创造了中国市场…

视觉分割的定义与性能度量

文章目录 视觉分割的定义语义分割(Semantic Segmentation)实例分割(instance Segmentation)全景分割(Panoptic Segmentation)视频语义分割(Video Semantic Segmentation)视频实例分割(Video instance Segmentation)视频全景分割(Video Panoptic Segmentation)各任务对比 视觉分…

苹果Mac安装adobe软件报错“installer file may be damaged”解决方案

最近Mac电脑系统的有小伙伴在安装PS、AI、AE、PR等软件&#xff0c;出现了一个错误&#xff0c;让人头疼不已&#xff0c;苦苦找寻&#xff0c;也找不到完美的解决方法。让我们来一起看看吧&#xff01; 很多小伙伴都喜欢苹果电脑&#xff0c;但是在安装外来软件时&#xff0c;…

广州数据中心机房搬迁验收要求

1.验收要求 新机房装修工程全部竣工&#xff0c;各类环境设备安装到位&#xff0c;包括空调、UPS、柴油发电机等设备安装调试完毕&#xff0c;机房接地、防雷、消防系统检验合格&#xff0c;机房综合布线工作完成&#xff0c;机房各项环境指标达标&#xff0c;机房整体通过验收…

嵌入式项目分享| 终极智能手表,全过程+全开源分享

这是一个非常完整的智能手表开源项目,功能齐全,且资料开源,如果你是:自己平时喜欢diy的工程师,想要提升开发技能的学生,马上要做毕设的大四学生,这个手表很值得一做,别错过了~~ 所有开源的资料以及原文链接见文末。 先来看下这个手表的功能: 首先,是一个可以佩戴的手…

进程、CPU、MMU与PCB之间的关系

目录 进程与cpu&#xff08;中央处理器&#xff09; 源代码、程序、cpu与进程的关系 cpu超线程 CPU的简易架构与处理数据过程 进程与MMU&#xff08;内存管理单元&#xff09; mmu作用 cpu和mmu的关系 进程与PCB&#xff08;进程控制块&#xff09; PCB介绍与内部成员…

PMBOK® 第六版 实施整体变更控制

目录 读后感—PMBOK第六版 目录 对于变化的态度&#xff0c;个人引用两句加以阐释&#xff0c;即“流水不腐&#xff0c;户枢不蠹”与“不以规矩&#xff0c;不能成方圆”。这看似相互矛盾&#xff0c;实则仿若两条腿总是一前一后地行进。有一个典型的例子&#xff0c;“自由美…

CentOS7环境脚本一键安装MySQL8

安装包准备 获取下载地址 选择对应的下载版本&#xff0c;如下图&#xff0c;右键RPM Bundle的Download&#xff0c;复制下载链接地址 下载安装包 [hadoopnode3 installfile]$ wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.31-1.el7.x86_64.rpm-bund…

Android View点击事件分发原理,源码解读

View点击事件分发原理&#xff0c;源码解读 前言1. 原理总结2.1 时序图总结2.2 流程图总结 2. 源码解读2.1 Activity到ViewGroup2.2 ViewGroup事件中断逆序搜索自己处理点击事件ViewGroup总结 2.3 ViewOnTouchListeneronTouchEvent 3. 附录&#xff1a;时序图uml代码 前言 两年…

mysql查询2个日期之间的数据,表字段只有年和月,无日期字段查询的解决

1.核心mysql查询 SELECT * FROM 表名 WHERE CONCAT(year, -, LPAD(month, 2, 0)) > 2022-02-08 AND CONCAT(year, -, LPAD(month, 2, 0)) < 2024-06-06;2.表结构 CREATE TABLE ys_datezzq (id int(10) NOT NULL AUTO_INCREMENT,bid int(10) NOT NULL DEFAULT 0 COMMEN…

如何下载植物大战僵尸杂交版,最全攻略来了

《植物大战僵尸杂交版》由热爱原版游戏的B站UP主“潜艇伟伟迷”独立开发&#xff0c;带来了创新的游戏体验。如果你是策略游戏的爱好者&#xff0c;下面这份全面的下载和游玩攻略将是你的理想选择。 游戏亮点&#xff1a; 杂交植物系统&#xff1a;结合不同植物特性&#xff0c…

ctfshow 新春欢乐赛 web

web1 <?phphighlight_file(__FILE__); error_reporting(0);$content $_GET[content]; file_put_contents($content,<?php exit();.$content);?contentphp://filter/string.rot13|<?cuc flfgrz(yf /);?>|/resourceshell.php绕过死亡exit 但是我发现个问题就是…

6.26作业

1.整理思维导图 2.统计家目录下.c文件的个数 ls ~/*.c | wc -l 3.终端输入一个.sh文件&#xff0c;判断文件是否由可执行权限&#xff0c;如果有可执行权限运行脚本&#xff0c;没有可执行权限添加可执行权限后&#xff0c;再运行脚本 #!/bin/bash read -p "请输入一个.…

【C语言】字符/字符串+内存函数

目录 Ⅰ、字符函数和字符串函数 1 .strlen 2.strcpy 3.strcat 4.strcmp 5.strncpy 6.strncat 7.strncmp 8.strstr 9.strtok 10.strerror 11.字符函数 12. 字符转换函数 Ⅱ、内存函数 1 .memcpy 2.memmove 3.memcmp Ⅰ、字符函数和字符串函数 1 .strlen 函数原型&#xff1a;…

UNIAPP编译到微信小程序时,会多一层以组件命名的标签

UNIAPP编译到微信小程序时&#xff0c;会多一层以组件命名的标签 解决方案 可以配置virtualHost来配置 export default {options: {virtualHost: true} }