当前位置: 首页 > news >正文

【Go】excelize库实现excel导入导出封装(三),基于excel模板导出excel

前言

大家好,这里是符华~

关于excelize库实现excel导入导出封装,我已经写了两篇了,我想要的功能基本已经实现了,现在还差一个模板导出,这篇文章就来讲讲如何实现用模板导出excel。

前两篇:

【Go】excelize库实现excel导入导出封装(一),自定义导出样式、隔行背景色、自适应行高、动态导出指定列、动态更改表头

【Go】excelize库实现excel导入导出封装(二),基于map、多个sheet、多级表头、树形结构表头导出,横向、纵向合并单元格导出


根据模板导出excel,在开发中也是经常会遇到的一种导出方式。一想到模板导出,我自然而然就想到了Java里的 easypoi 框架。easypoi 呢在Java里面也是一个操作excel使用率很高的框架,然后这个框架的模板导出呢,是有设定模板指令的,就是下面这种:

在这里插入图片描述

用的时候就是这样:

在这里插入图片描述

填充数据就是把数据放到map里面,map的key对应模板里面设置的字段名(比如 name、sfz 这几个字段名),map的value就是我们要导出的结果值。

然后呢我就想,Go里面用模板导出应该也是用模板指令的吧?但是呢其实在 excelize 库中,它并不支持类似的模板指令,这么看来 excelize 库好像不支持用模板导出?那有啥办法可以实现这个功能?


欸嘿,还真有,只不过这个模板导出呢就和 excelize 没啥关系了,但因为是自己封装导入导出,那我就干脆把这个模板导出也一起封装进来、一起放到这个专栏系列里面了。

实现

excelize 虽然没有模板指令,但是Go标准库中的 text/templatehtml/template 包提供了强大的模板功能,所以我们本篇文章的实现也是基于 html/template 来实现的。

html/template 的模板指令和 easypoi 的模板指令有点类似,但细节上还是有很大差异的,具体使用用法可以看看这篇文章:Go语言标准库之html/template详解 。

我们可以使用 text/templatehtml/template 来解析模板,但是需要注意的是,这两个库并不能直接解析excel模板,它们只能解析文本格式的文件,不能解析二进制格式的文件。

所以用的时候,我们准备好了一个excel模板时,还需要将这个excel文件另存为xml文件。

有了xml文件也不能直接用,有些地方的数据可能需要处理一下,比如遍历list的时候,需要将 range 遍历放到正确的位置。

检查好之后,再使用 template.ParseFiles 函数解析这个xml文件,接下来就可以填充数据了。填充好后,将渲染模板并输出为excel文件。

准备模板

我们先准备好excel模板

在这里插入图片描述

然后再另存为xml文件

在这里插入图片描述

拿到xml文件后,先不要急着解析,先格式化一下进行检查,如果数据太多,我们按照关键字搜索

在这里插入图片描述

错误的位置:

在这里插入图片描述

改正的位置:

在这里插入图片描述

在这里插入图片描述

按照上面的方法检查并改正好之后,保存好,这样我们就可以开始解析这个xml模板了。

开始

// 模板导出
func ExportTemplate() {// 准备结构体数据var list = []Test{{"fuhua", "符华", "fuhua@123.com", "太虚剑派", false, "1", 1},{"baiye", "白夜", "baiye@123.com", "天命科技有限公司", false, "2", 1},{"chiling", "炽翎", "chiling@123.com", "太虚剑派", false, "2", 2},{"yunmo", "云墨", "yunmo@123.com", "太虚剑派", false, "1", 2},{"yuelun", "月轮", "yuelun@123.com", "天命科技有限公司", false, "1", 1},{"xunyu", "迅羽", "xunyu@123.com", "天命科技有限公司", true, "2", 124},}// 准备map数据data := map[string]any{"name":     "符华","sex":      "女","birthday": "2000-10-01","jg":       "广东省","sfz":      "123456789111111111","gzdw":     "天命科技","email":    "fuhua@123.com","phone":    "13188888888","workList": []map[string]any{{"date": "2019-01-01~2020-10-01", "unit": "逐火之蛾", "post": "普通员工", "sfzz": "否"},{"date": "2020-10-20~2022-09-15", "unit": "太虚剑派", "post": "CEO", "sfzz": "否"},{"date": "2022-10-01~至今", "unit": "天命科技", "post": "经理", "sfzz": "是"},},"list": list,}templatePath := "template\\测试模板导出.xml" // 模板路径outPath := "C:\\Users\\Administrator\\Desktop\\output.xlsx" // 输出路径err := excel.TemplateExport(templatePath, outPath, data)if err != nil {fmt.Println(err.Error())}fmt.Println("导出成功!")// 将excel下载到浏览器,第一个参数是模板路径、第二个参数是下载的文件名称(要带上后缀)、第三个参数是模板数据、第四个参数是http响应// excel.DownLoadByTemplate(templatePath,"output.xlsx",data,res)
}

excel 包下的 TemplateExport 函数:

// TemplateExport 基于excel的模板导出
func TemplateExport(templatePath, outPath string, data map[string]interface{}) error {// 解析模板tmpl, err := template.ParseFiles(templatePath)if err != nil {return errors.New("模板解析失败:" + err.Error())}// 创建输出文件file, err := os.Create(outPath)if err != nil {return errors.New("创建输出文件失败:" + err.Error())}defer file.Close()// 渲染模板并输出结果err = tmpl.Execute(file, data)if err != nil {return errors.New("模板数据渲染失败:" + err.Error())}return nil
}

excel 包下的 DownLoadByTemplate 函数:

// 根据模板下载文件:templatePath 模板路径,fileName 文件名称(需要加上后缀名),data 模板数据
func DownLoadByTemplate(templatePath, fileName string, data map[string]interface{}, res http.ResponseWriter) {// 解析模板tmpl, err := template.ParseFiles(templatePath)if err != nil {http.Error(res, "模板解析失败:"+err.Error(), http.StatusInternalServerError)return}// 设置响应头res.Header().Set("Content-Type", "text/html; charset=UTF-8")res.Header().Set("Content-Type", "application/octet-stream")res.Header().Set("Content-Disposition", "attachment; filename="+fileName)res.Header().Set("Access-Control-Expose-Headers", "Content-Disposition")// 渲染模板并输出结果err = tmpl.Execute(res, data)if err != nil {http.Error(res, "模板数据渲染失败:"+err.Error(), http.StatusInternalServerError)}
}

导出结果:

在这里插入图片描述

这样子我们就实现了根据模板导出excel辣~

最后

这里是 源码

如果大家觉得本篇文章或专栏对你有所帮助或者觉得写得还可以的话,欢迎大家多多给博主 点赞关注 支持一下哦😘下载源码的时候顺便给博主点个Star😘你动动手指就是对我莫大的鼓励🥰

相关文章:

  • Linux shell编程学习笔记39:df命令
  • Go语言使用gosseract 库来进行图像文字识别,识别出来的中文是乱码的?如何解决?
  • linux项目部署(jdk,tomcat,mysql,nginx,redis)
  • python学习笔记10(选择结构2、循环结构1)
  • 【Linux】Linux系统编程——Linux目录结构
  • 【驱动】TI AM437x(内核调试-02):dynamic 动态打印调试
  • 微信小程序Canvas画布绘制图片、文字、矩形、(椭)圆、直线
  • Spring整理-Spring框架的国际化
  • 根据gbt81702008数值修约的C#函数
  • Logstash:迁移数据到 Elasticsearch
  • MySQL 8.0中新增的功能(八)
  • Python+甘特图及标签设置
  • 计算机网络层之ICMP与IGMP
  • 已解决java.lang.NoSuchFieldException异常的正确解决方法,亲测有效!!!
  • Python 网络爬虫入门详解
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • CSS实用技巧
  • gops —— Go 程序诊断分析工具
  • input的行数自动增减
  • javascript 总结(常用工具类的封装)
  • Javascript编码规范
  • Laravel 实践之路: 数据库迁移与数据填充
  • mysql 数据库四种事务隔离级别
  • PAT A1017 优先队列
  • Python 反序列化安全问题(二)
  • 基于Android乐音识别(2)
  • 基于游标的分页接口实现
  • 今年的LC3大会没了?
  • 聊聊flink的BlobWriter
  • 配置 PM2 实现代码自动发布
  • 使用agvtool更改app version/build
  • 最简单的无缝轮播
  • Spring第一个helloWorld
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • $L^p$ 调和函数恒为零
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (2020)Java后端开发----(面试题和笔试题)
  • (3)nginx 配置(nginx.conf)
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (一)kafka实战——kafka源码编译启动
  • (一)SvelteKit教程:hello world
  • (转)EOS中账户、钱包和密钥的关系
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)shell调试方法
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .net经典笔试题
  • .NET开发不可不知、不可不用的辅助类(一)
  • .NET与 java通用的3DES加密解密方法
  • .NET正则基础之——正则委托
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • @RequestMapping 的作用是什么?