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

1 简介

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)
}
  • 输出文件:
    在这里插入图片描述
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Java中实现Excel导出可以使用Apache POI库。要实现固定列宽自动换行,可以使用CellStyling来设置单元格样式。 以下是一个示例代码,可以实现导出Excel固定列宽自动换行的功能: ```java import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ExcelExporter { public static void export(String[][] data, String[] headers, String fileName) throws IOException { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); // 设置列宽度为15个字符 sheet.setColumnWidth(0, 15 * 256); sheet.setColumnWidth(1, 15 * 256); sheet.setColumnWidth(2, 15 * 256); // 创建头行 Row headerRow = sheet.createRow(0); for (int i = 0; i < headers.length; i++) { Cell cell = headerRow.createCell(i); cell.setCellValue(headers[i]); } // 创建数据行 CreationHelper createHelper = workbook.getCreationHelper(); for (int i = 0; i < data.length; i++) { Row row = sheet.createRow(i + 1); for (int j = 0; j < data[i].length; j++) { Cell cell = row.createCell(j); cell.setCellValue(createHelper.createRichTextString(data[i][j])); // 设置单元格样式,包括固定列宽自动换行 XSSFCellStyle style = (XSSFCellStyle) workbook.createCellStyle(); style.setWrapText(true); cell.setCellStyle(style); } } // 写入文件 FileOutputStream fileOut = new FileOutputStream(fileName); workbook.write(fileOut); fileOut.close(); workbook.close(); } } ``` 该代码将数据和头作为输入,并将其写入Excel文件中。在创建单元格时,使用CellStyling来设置单元格样式,并使用setWrapText方法来启用自动换行固定列宽可以通过setColumnWidth方法来设置。 使用该代码的示例: ```java public class Main { public static void main(String[] args) throws IOException { String[][] data = { {"John Smith", "Software Engineer", "San Francisco, CA"}, {"Jane Doe", "Product Manager", "New York, NY"}, {"Bob Johnson", "Sales Representative", "Chicago, IL"} }; String[] headers = {"Name", "Title", "City"}; ExcelExporter.export(data, headers, "output.xlsx"); } } ``` 该代码将生成一个名为“output.xlsx”的文件,其中包含固定列宽自动换行的数据和头。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微雨停了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值