【go】Excelize处理excel表 带合并单元格、自动换行与固定列宽的文件导出

文章目录

  • 1 简介
  • 2 相关需求与实现
    • 2.1 导出带单元格合并的excel文件
    • 2.2 导出增加自动换行和固定列宽的excel文件

1 简介

  • 之前整理过使用Excelize导出原始excel文件与增加数据校验的excel导出。【go】Excelize处理excel表 带数据校验的文件导出

  • 本文整理使用Excelize导出带单元格合并的excel文件与导出增加自动换行和固定列宽的excel文件

2 相关需求与实现

2.1 导出带单元格合并的excel文件

  • 需求:入参是一个map,其键是每个sheet页的名字,其值是一个二维切片。在每个sheet页中依次写入切片中的数据。返回文件名和错误信息。
    合并单元格:前三列,如果此格和上行格相同,则合并
  • 代码:
// 增加合并单元格的文件导出
func WriteExcelMerge(datas map[string][][]string) (string, error) {
	file := excelize.NewFile()

	for sheetName, data := range datas {
		index, _ := file.NewSheet(sheetName)
		for i, row := range data {
			for j, val := range row {
				// 列行数字索引转excel坐标索引
				cellName, _ := excelize.CoordinatesToCellName(j+1, i+1)
				// 设置,写入
				file.SetCellValue(sheetName, cellName, val)
			}
		}
		// 创建表格
		file.SetActiveSheet(index)
	}

	for sheet, _ := range datas {
		// 获取表格中的所有行
		rows, err := file.GetRows(sheet)
		if err != nil {
			return "", err
		}

		for i := 1; i < len(rows); i++ {
			currRow := rows[i]
			prevRow := rows[i-1]

			// 判断前3列是否相等
			if currRow[0] == prevRow[0] &&
				currRow[1] == prevRow[1] &&
				currRow[2] == prevRow[2] {

				// 合并相邻单元格
				for j := 1; j <= 3; j++ {
					cellName1, _ := excelize.CoordinatesToCellName(j, i) // 列,行
					cellName2, _ := excelize.CoordinatesToCellName(j, i+1)
					err := file.MergeCell(sheet, cellName1, cellName2)
					if err != nil {
						return "", err
					}
				}
			}
		}
	}

	filename := "aaa" + ".xlsx"

	// 创建目录
	_, err := os.ReadDir("aaa/")
	if err != nil {
		// 不存在就创建
		err = os.MkdirAll("aaa/", fs.ModePerm)
		if err != nil {
			return "", err
		}
	}

	file.DeleteSheet("Sheet1")

	err = file.SaveAs("aaa/" + filename)
	if err != nil {
		return "", err
	}
	return filename, nil
}

func main() {

	datas := make(map[string][][]string)
	datas["xxx"] = [][]string{{"a", "b", "c", "D1", "E1", "G1", "H1", "I1"}, {"a", "b", "c", "D1"}, {"a", "b", "c", "D1"}}
	datas["yyy"] = [][]string{{"X1", "Y1", "Z1"}, {"X2", "Y2", "Z2"}, {"X3", "Y3", "Z3"}}
	fileName, err := WriteExcelMerge(datas)
	if err != nil {
		fmt.Println("Write excel error: ", err)
		return
	}

	fmt.Println("Write excel success, file name is: ", fileName)
}
  • 输出文件:
    合并:
    在这里插入图片描述
    未合并:在这里插入图片描述

2.2 导出增加自动换行和固定列宽的excel文件

  • 需求:同上
    其中,第一列设置自动换行+固定列宽20;第二列固定列宽20
  • 代码:
func WriteExcelAuto(datas map[string][][]string, widths map[string]float64, wrapTexts []string) (string, error) {
	file := excelize.NewFile()

	// 自动换行
	styleID, err := file.NewStyle(&excelize.Style{
		Alignment: &excelize.Alignment{
			WrapText: true,
		},
	})
	if err != nil {
		return "", err
	}

	for sheetName, data := range datas {

		index, _ := file.NewSheet(sheetName)
		for i, row := range data {
			for j, val := range row {
				// 列行数字索引转excel坐标索引
				cellName, _ := excelize.CoordinatesToCellName(j+1, i+1)
				// 设置,写入
				file.SetCellValue(sheetName, cellName, val)
			}
		}

		// 设置自动换行
		for _, v := range wrapTexts {
			file.SetColStyle(sheetName, v, styleID)
		}

		// 设置列宽
		for k, v := range widths {
			file.SetColWidth(sheetName, k, k, v)
		}

		// 创建表格
		file.SetActiveSheet(index)
	}
	filename := "aaa" + ".xlsx"

	// 创建目录
	_, err = os.ReadDir("aaa/")
	if err != nil {
		// 不存在就创建
		err = os.MkdirAll("aaa/", fs.ModePerm)
		if err != nil {
			return "", err
		}
	}

	file.DeleteSheet("Sheet1")

	err = file.SaveAs("aaa/" + filename)
	if err != nil {
		return "", err
	}
	return filename, nil
}

func main() {

	datas := make(map[string][][]string)
	datas["xxx"] = [][]string{{"AAAAAAAAAAAAAAAAAAAAA", "B1", "C1", "d1", "E1", "G1", "H1", "I1"}, {"A2", "B2", "C2"}, {"A3", "B3", "C3"}}
	datas["yyy"] = [][]string{{"X1", "Y1", "Z1"}, {"X2", "Y2", "Z2"}, {"X3", "Y3", "Z3"}}

	widths := map[string]float64{
		"A": 20,
		"B": 20,
	}

	wraps := []string{
		"A",
	}
	fileName, err := WriteExcelAuto(datas, widths, wraps)
	if err != nil {
		fmt.Println("Write excel error: ", err)
		return
	}

	fmt.Println("Write excel success, file name is: ", fileName)
}
  • 输出文件:
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android 消息发布订阅框架:EventBus

目录 1.是什么 2.如何使用 3.五种线程模型 4.Eventbus2和Eventbus3的区别 一、是什么 EventBus是一款发布/订阅事件总线的框架&#xff0c;使用它可以进行模块间通信、解耦。它可以使用很少的代码&#xff0c;来实现多组件之间的通信&#xff0c;非常的方便。 为什么使用它…

十七、(正点原子)Linux LCD驱动

一、Framebuffer设备 在 Linux 中应用程序通过操作 RGB LCD 的显存来实现在 LCD 上显示字符、图片等信息。 先来看一下裸机 LCD 驱动如下&#xff1a; ①、初始化 I.MX6U 的 eLCDIF 控制器&#xff0c;重点是 LCD 屏幕宽(width)、高(height)、 hspw、 hbp、 hfp、 vspw…

go中map

文章目录 Map简介哈希表与Map的概念Go语言内建的Map类型Map的声明Map的初始化Map的访问Map的添加和修改Map的删除Map的遍历 Map的基本使用Map的声明与初始化Map的访问与操作Map的删除Map的遍历Map的并发问题实现线程安全的Map 3. Map的访问与操作3.1 访问Map元素代码示例&#…

微信小程序 button样式设置为图片的方法

微信小程序 button样式设置为图片的方法 background-image background-size与background-repeat与border:none;是button必须的 <view style" position: relative;"><button class"customer-service-btn" style"background-image: url(./st…

新华三H3CNE网络工程师认证—VLAN使用场景与原理

通过华三的技术原理与VLAN配置来学习&#xff0c;首先介绍VLAN&#xff0c;然后介绍VLAN的基本原理&#xff0c;最后介绍VLAN的基本配置。 文章目录 一、传统以太网问题1、广播域范围过大2、分割广播域 二、如何实现VLAN1、VLAN技术达到的效果2、VLAN数值的编号范围3、仿真&am…

这届打工人,快把单休卷成职场用工标配了……

最近&#xff0c;小柴有个朋友跟小柴吐槽&#xff0c;自己被「灵活就业」大半年了&#xff0c;有点扛不住&#xff0c;就准备去送外卖&#xff0c;结果第一天赚了38&#xff0c;反手电瓶车罚了50…… 心灰意冷的他&#xff0c;最终还是在某BOSS上充个值&#xff0c;没日没夜的投…

手持式气象站:便携科技,掌握微观气象的利器

手持式气象站&#xff0c;顾名思义&#xff0c;是一种可以随身携带的气象监测设备。它小巧轻便&#xff0c;通常配备有温度、湿度、风速、风向、气压等多种传感器&#xff0c;能够实时测量并显示各种气象参数。不仅如此&#xff0c;它还具有数据存储、数据传输、远程控制等多种…

搭建博客系统#Golang

WANLI 博客系统 项目介绍 基于vue3和gin框架开发的前后端分离个人博客系统&#xff0c;包含md格式的文本编辑展示&#xff0c;点赞评论收藏&#xff0c;新闻热点&#xff0c;匿名聊天室&#xff0c;文章搜索等功能。 点击跳转&#xff1a;Github 项目开源地址 功能展示 B 站…

实战篇(十):使用Processing创建可爱花朵:实现随机位置、大小和颜色的花朵

使用Processing创建可爱花朵 0.效果预览1. 引言2. 设置Processing环境3. 创建花朵类4. 实现花瓣绘制5. 绘制可爱的笑脸6. 鼠标点击生成花朵7. 完整代码8. 总结与扩展0.效果预览 在本教程中,我们将使用Processing编程语言来创建一个可爱的花朵生成器。通过封装花朵为一个类,并…

使用shedlock实现分布式互斥执行

前言 前序章节&#xff1a;springboot基础(82):分布式定时任务解决方案shedlock 如果你不清楚shedlock&#xff0c;建议先阅读前序章节&#xff0c;再来查看本文。 如果我们不在spring环境下&#xff0c;如何使用shedlock实现分布式互斥执行&#xff1f; 我们可以使用shedl…

Elasticsearch 7.x入门学习-Java API操作

1 创建项目 在idea开发工具中创建Maven项目 修改 pom 文件&#xff0c;增加 Maven 依赖关系 <dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</versi…

ubuntu2204配置anacondacuda4090nvidia驱动

背景 某个机房的几台机器前段时间通过dnat暴露至公网后被入侵挖矿&#xff0c;为避免一些安全隐患将这几台机器执行重装系统操作&#xff1b; 这里主要记录配置nvidia驱动及cuda&anaconda。 步骤 大概分为几个步骤 禁用nouveau配置grub显示菜单install nvidia-driveri…

Linux云计算 |【第一阶段】ENGINEER-DAY3

主要内容&#xff1a; LVM逻辑卷管理、VDO、RAID磁盘阵列、进程管理 一、新建逻辑卷 1、什么是逻辑卷 逻辑卷&#xff08;Logical Volume&#xff09;是逻辑卷管理&#xff08;Logical Volume Management&#xff0c;LVM&#xff09;系统中的一个概念。LVM是一种用于磁盘管理…

SpringBoot集成MQTT实现交互服务通信

引言 本文是springboot集成mqtt的一个实战案例。 gitee代码库地址&#xff1a;源码地址 一、什么是MQTT MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;&#xff0c;是一种基于发布/订阅&#xff08;publish/subscribe&…

[Armbian] 部署Docker版Home Assistent,安装HACS并连接米家设备

title: [Armbian] 部署Docker版Home Assistent&#xff0c;安装HACS并连接米家设备 date: 2024-07-21T10:51:23Z lastmod: 2024-07-21T11:40:39Z [Armbian] 部署Docker版Home Assistent&#xff0c;安装HACS并连接米家设备 官网&#xff1a;Home Assistant (home-assistant.i…

sql常见50道查询练习题

sql常见50道查询练习题 1. 表创建1.1 表创建1.2 数据插入 2. 简单查询例题(3题&#xff09;2.1 查询"李"姓老师的数量2.2 查询男生、女生人数2.3 查询名字中含有"风"字的学生信息 3. 日期相关例题(6题&#xff09;3.1 查询各学生的年龄3.2 查询本周过生日的…

Yolo-World网络模型结构及原理分析(一)——YOLO检测器

文章目录 概要一、整体架构分析二、详细结构分析YOLO检测器1. Backbone2. Head3.各模块的过程和作用Conv卷积模块C2F模块BottleNeck模块SPPF模块Upsampling模块Concat模块 概要 尽管YOLO&#xff08;You Only Look Once&#xff09;系列的对象检测器在效率和实用性方面表现出色…

【GraphRAG】微软 graphrag 效果实测

GraphRAG 本文将基于以下来源&#xff0c;对Microsoft GraphRAG分析优缺点、以及示例实测分析。 1. Source 代码仓库&#xff1a; Welcome to GraphRAGhttps://microsoft.github.io/graphrag/ 微软文章1&#xff08;2024.2.13&#xff09;&#xff1a;GraphRAG: Unlocking…

通过albumentation对目标检测进行数据增强(简单直接)

albumentation官方文档看不懂&#xff1f;xml文件不知道如何操作&#xff1f;下面只需要修改部分代码即可上手使用 要使用这个方法之前需要按照albumentation这个库还有一些辅助库,自己看着来安装就行 pip install albumentation pip install opencv-python pip install json…

阿尔泰科技利用485模块搭建自动灌溉系统实现远程控制

自动灌溉系统又叫土壤墒情监控系统&#xff0c;土壤墒情监控系统主要实现固定站无人值守情况下的土壤墒情数据的自动采集和无线传输&#xff0c;数据在监控中心自动接收入库&#xff1b;可以实现24小时连续在线监控并将监控数据通过有线、无线等传输方式实时传输到监控中心生成…