【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😘你动动手指就是对我莫大的鼓励🥰

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis原理篇(Dict的收缩扩容机制和渐进式rehash)

Dict(即字典) Redis是一种键值型数据库,其中键与值的映射关系就是Dict实现的。 Dict通过三部分组成:哈希表(DictHashTable),哈希节点(DictEntry),字典(Dict&#xff09…

JAVA静态引擎企业网站源码带文档

JAVA静态引擎企业网站源码带文档 系统介绍: 1.网站后台采用主流的 SSM 框架 jsp JSTL,网站前台采用freemaker静态化模版引擎生成html5 2.因为是生成的html,无需重复读取数据库,所以访问速度快,轻便,对服务器…

group by 查询慢的话,如何优化?

1、说明 根据一定的规则,进行分组。 group by可能会慢在哪里?因为它既用到临时表,又默认用到排序。有时候还可能用到磁盘临时表。 如果执行过程中,会发现内存临时表大小到达了上限(控制这个上限的参数就是tmp_table…

vue中使用js-doc

安装依赖 安装vue-template-compiler npm install ​vue-template-compiler​ 安装minami npm install minami 安装js-doc npm install js-doc 根目录下创建 .jsdoc.conf.json 内容: {"tags": {"allowUnknownTags": true,// 指定所用词…

LeetCode264. 丑数 II(相关话题:多重指针动态规划)

题目描述 给你一个整数 n ,请你找出并返回第 n 个 丑数 。丑数 就是质因子只包含 2、3 和 5 的正整数。 示例 1: 输入:n 10 输出:12 解释:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。示例 2&am…

给Flutter + FireBase 增加 badge 徽章,App启动器 通知红点。

在此之前需要配置好 firebase 在flutter 在项目中。(已经配置好的可以忽略此提示) Firebase 配置教程:flutter firebase 云消息通知教程 (android-安卓、ios-苹果)_flutter firebase_messaging ios环境配置-CSDN博客 由于firebase 提供的消息…

数据分享|纯净音自然多轮对话数据集——语音大模型

在过去的一年里,大语言模型一路高歌猛进,让人惊艳的产品不断被推出。语音大模型也迎来突破,其中就包括还原度越来越高的声音复刻技术。 优秀的语音复刻性能离不开高质量的训练数据支撑。语音大模型构建需要大量的自然数据,尽可能…

myql进阶-一条查询sql在mysql的执行过程

目录 1. 流程图 2. 各个过程 2.1 连接器 2.2 分析器 2.3 优化器 2.4 执行器 2.5 注意点 1. 流程图 2. 各个过程 假设我们执行一条sql语句如下: select * from t_good where good_id 1 2.1 连接器 首先我们会和mysql建立连接,此时就会执行到连接…

世邦spon IP网络对讲广播系统任意文件上传漏洞

产品介绍 世邦通信IP网络对讲广播系统采用领先的IPAudio™技术,将音频信号以数据包形式在局域网和广域网上进行传送,是一套纯数字传输系统。 漏洞描述 spon IP网络对讲广播系统存在任意文件上传漏洞,攻击者可以通过构造特殊请求包上传恶意后门文件,从…

Linux环境之Ubuntu安装Docker流程

今天分享Linux环境之Ubuntu安装docker流程,Docker 是目前非常流行的容器,对其基本掌握很有必要。下面我们通过阿里云镜像的方式安装: 本来今天准备用清华大学镜像安装呢,好像有点问题,于是改成阿里云安装了。清华安装…

SpringBoot之优化高并发场景下的HttpClient并提升QPS

HttpClient优化思路 使用连接池(简单粗暴) 长连接优化(特殊业务场景) httpclient和httpget复用 合理的配置参数(最大并发请求数,各种超时时间,重试次数) 异步请求优化&#xff0…

Qt/QML编程学习之心得:slider(34)

滑条slider,有时也成为进度条progressbar,在GUI界面中也是经常用到的。 import QtQuick 2.9 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.2ApplicationWindow {id:rootvisible: truewidth: 1920height: 720//title: qsTr("Hello World&q…

【操作系统】在阅读论文:OrcFS: Orchestrated file system for flash storage是需要补充的基础知

在阅读论文:OrcFS: Orchestrated file system for flash storage是需要补充的基础知识 这篇论文是为了解决软件层次之间的信息冗余问题 To minimize the disk traffic, the file system buffers the updates and then flushes them to the disk as a single unit, …

鸿蒙开发环境搭建-高频环境问题解决

1.Node版本问题 由于SDK的部分工具依赖Node.js运行时,推荐使用配套API版本的Node.js,保证工程的兼容性。 匹配关系见下表: API LevelNode.js支持范围API Level≤914.x(≥14.19.1)、16.xAPI Level>914.x&#xff0…

计算机msvcp140.dll丢失如何解决,分享3个简单有效的方法

在计算机系统运行过程中,用户有时会遇到一个常见的错误提示——msvcp140.dll文件缺失,这一问题的发生往往会导致部分软件无法正常启动或运行。“针对计算机系统中出现的msvcp140.dll缺失问题,小编将详尽阐述并探讨5种有效的解决策略。每一种方…

Linux 内核学习 3a - 如何查看虚拟内存和物理内存,以及虚拟内存和物理内存之间转换

/proc/iomem, ioremap(), mmap() The kernel manages device resources like registers as physical addresses(物理地址). These are the addresses in /proc/iomem. The physical address is not directly useful to a driver; it must use ioremap() to map the space and …

【PaperReading】2. MM-VID

Category Content 论文题目 MM-VID: Advancing Video Understanding with GPT-4V(ision) 作者 Kevin Lin, Faisal Ahmed, Linjie Li, Chung-Ching Lin, Ehsan Azarnasab, Zhengyuan Yang, Jianfeng Wang, Lin Liang, Zicheng Liu, Yumao Lu, Ce Liu, Lijuan Wang (Microso…

git ssh key 配置

一、Profile Settings-->SSH Keys 我们点击这里会有详情的文档介绍生成sshkey。 ssh-keygen -t rsa -b 2048 -C "邮箱" --回车... 将生成的id_rsa.pub粘贴到如下保存 git config --global user.name "用户名" git config --global user.email "邮…

SpringBoot使用MockMVC单元测试Controller

对模块进行集成测试时,希望能够通过输入URL对Controller进行测试,如果通过启动服务器,建立http client进行测试,这样会使得测试变得很麻烦,比如启动速度慢,测试验证不方便,依赖网络环境等&#…

Unity中Shader面片一直面向摄像机

文章目录 前言一、实现思路1、 我们要实现模型面片一直跟着摄像机旋转,那么就需要用到旋转矩阵2、确定 原坐标系 和 目标坐标系3、确定旋转后坐标系基向量二、确定旋转后 坐标系基向量 在 原坐标系 下的值1、Z轴基向量2、假设Y轴基向量 和 世界空间下 的Y轴方向一致竖直向上3、…