Golang Excelize 2.4.1 发布:强大的电子表格处理 API

Golang Excelize 2.4.1 发布:强大的电子表格处理 API github.com/xuri/excelize

Excelize 是一个用纯 Go 语言编写的库,提供了一系列函数,允许您读写 XLSX / XLSM / XLTM 文件。支持读写由 Microsoft Excel™ 2007 及更高版本生成的电子表格文档。通过高兼容性支持复杂组件,并提供了流式 API,用于从包含大量数据的工作表中生成或读取数据。

GitHub: github.com/xuri/excelize

我们很高兴地宣布版本 2.4.1 的发布。本次发布包含了一些新的功能领域和大量的错误修复。

变更摘要可在发布说明中查看。完整的变更列表可在更新日志中找到。

发布说明

本次发布中最值得注意的变更有:

兼容性

将 Go Modules 导入路径更改为 github.com/xuri/excelize/v2

重要特性

  • 支持在流模式下设置列宽,相关议题 #625
  • 支持在流模式下合并单元格,相关议题 #826
  • 新增支持 2 个公式函数:BESSELK, BESSELY
  • 公式计算引擎现在支持定义名称引用
  • 为图表 xAxis 和 yAxis 添加禁用选项
  • 函数 AddPivotTable 支持通过定义名称引用源数据范围,相关议题 #856
  • 以下函数现在是并发安全的,相关议题 #861
    • AddPictureGetPicture 并发插入或从工作表中获取图片
    • RowsCols 并发迭代行和列
    • SetSheetRow 并发设置工作表中某一行的单元格
    • SetCellStyle 并发设置单元格样式
    • NewStyle 并发创建样式
  • 导出 24 个函数的错误信息

提升兼容性

  • 改进了对默认 XML 命名空间属性的兼容性,修复了在某些情况下生成损坏文件的问题
  • 改进了与非标准页面设置属性的兼容性,修复了在某些情况下打开电子表格失败的问题
  • 在共享字符串表中添加计数属性
  • 移除使用时间设置单元格值时对 UTC 时区的要求,相关议题 #409
  • 改进了与转义字面字符串中 XML 控制字符的兼容性
  • 将导出的字段 File.XLSX 重命名为 File.Pkg
  • 更改 NewSheetGetSheetIndexDeleteSheet 的 sheet 名称不区分大小写,解决议题 #873
  • 修复条件格式中缺失的 pivot 属性,解决议题 #883
  • 改进了与页面布局中无效首页页码属性的兼容性
  • SetCellRichText 添加最大字符限制并修复缺失的保留字符

错误修复

  • 修复 12/24 小时时间格式解析错误,解决议题 #823 和 #841
  • 修复在某些情况下无法通过 GetComments 获取评论的问题,解决议题 #825
  • 修复在多作者情况下获取和添加评论时的问题,解决议题 #829 和 #830
  • 修复重新创建工作表时无效的文件路径和重复的命名空间,解决议题 #834
  • 修复当 showOutlineSymbolssummaryBelowsummaryRight 属性值为 false 时,设置大纲属性不生效的问题
  • 通过 GetRows 避免工作表末尾出现空行,解决议题 #842
  • 修复获取行值时缺失公式单元格的问题,解决议题 #855
  • 修复 IF 函数内部和外部的比较失败问题,解决议题 #858
  • 修复 GetRowHeight 实际上获取的是下一行高度的问题
  • 修复获取和删除定义名称时范围不正确的问题,解决议题 #879
  • 定义名称中的属性 LocalSheetID 应等于 SheetIndex 而不是 SheetID
  • 修复设置列样式时缺失设置每个单元格样式的问题,解决议题 #467
  • 防止在创建数据透视表时提供不正确的范围作为 PivotTableRange 导致 panic
  • 修复读取小数精度问题,解决议题 #848 和 #852
  • 转义下拉列表中的 XML 字符,避免生成损坏的文件,解决议题 #971
  • 修复下拉列表中字符计数限制不正确的问题,解决议题 #972
  • 修复在某些情况下,由于 Excel 时间解析问题导致读取带有数字格式的单元格值时 CPU 使用率过高的问题,解决议题 #974
  • 修复在某些情况下自定义数字格式中的月份解析错误

性能

  • SaveSaveAs 上减少约 19% 的冗余内存使用

杂项

  • 修复代码安全问题 CWE-190 和 CWE-681
  • 依赖模块已更新
  • 单元测试和 godoc 已更新
  • 使用 GitHub Action 进行单元测试
  • 多语言文档网站已更新,支持阿拉伯语、德语、西班牙语、英语、法语、俄语、中文、日语和韩语

更多关于Golang Excelize 2.4.1 发布:强大的电子表格处理 API的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

我在一个项目中使用Excelize,它非常棒。很高兴看到你也在论坛上。

更多关于Golang Excelize 2.4.1 发布:强大的电子表格处理 API的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的——我一直觉得有点好笑,OpenXML SDK 是微软开发的,但它却是处理 XLSX 最糟糕的库之一。它速度很快,但是天哪,要让输出完美无缺真是太痛苦了。EPPlus 还行,但在我使用 OpenXML 的那个项目时期,EPPlus 不支持 .NET Core,所以它根本不在考虑范围内。

今天刚开始使用它!我手头有一个项目,它接收数据库模式的JSON描述,并能根据该模式生成几种语言的模型。我想为某个使用Excel电子表格来定义模式的第三方应用程序添加支持,所以我用Excelize来生成正确格式的文件。

使用起来非常容易;我第一次尝试就成功了,这比我第一次尝试使用OpenXML SDK时要顺利得多!已经在GitHub上给它点了星!

Excelize 2.4.1 的发布确实带来了许多重要的改进和新特性,特别是在并发安全性和流式API方面。以下是对其中一些关键特性的代码示例说明:

1. 流模式下设置列宽和合并单元格

现在可以在流式写入时动态设置列宽和合并单元格,这对于处理大型数据集非常有用。

package main

import (
    "fmt"
    "github.com/xuri/excelize/v2"
)

func main() {
    f := excelize.NewFile()
    streamWriter, err := f.NewStreamWriter("Sheet1")
    if err != nil {
        fmt.Println(err)
        return
    }
    
    // 设置列宽
    if err := streamWriter.SetColWidth(2, 2, 20); err != nil {
        fmt.Println(err)
        return
    }
    
    // 合并单元格
    if err := streamWriter.MergeCell("A1", "C1"); err != nil {
        fmt.Println(err)
        return
    }
    
    // 写入数据
    if err := streamWriter.SetRow("A1", []interface{}{"合并的标题"}); err != nil {
        fmt.Println(err)
        return
    }
    
    if err := streamWriter.Flush(); err != nil {
        fmt.Println(err)
        return
    }
    
    if err := f.SaveAs("流式写入示例.xlsx"); err != nil {
        fmt.Println(err)
    }
}

2. 并发安全操作示例

多个函数现在支持并发安全调用,这对于高并发场景下的性能提升很有帮助。

package main

import (
    "fmt"
    "github.com/xuri/excelize/v2"
    "sync"
)

func main() {
    f := excelize.NewFile()
    var wg sync.WaitGroup
    
    // 并发设置单元格样式
    for i := 1; i <= 10; i++ {
        wg.Add(1)
        go func(row int) {
            defer wg.Done()
            style, _ := f.NewStyle(&excelize.Style{
                Font: &excelize.Font{Bold: true},
            })
            cell := fmt.Sprintf("A%d", row)
            f.SetCellValue("Sheet1", cell, fmt.Sprintf("并发行%d", row))
            f.SetCellStyle("Sheet1", cell, cell, style)
        }(i)
    }
    
    wg.Wait()
    f.SaveAs("并发示例.xlsx")
}

3. 新增公式函数使用

新增的BESSELK和BESSELY函数可以在公式计算中使用。

package main

import (
    "fmt"
    "github.com/xuri/excelize/v2"
)

func main() {
    f := excelize.NewFile()
    
    // 设置基础数据
    f.SetCellValue("Sheet1", "A1", 5.0)
    f.SetCellValue("Sheet1", "A2", 2.0)
    
    // 使用BESSELK函数
    f.SetCellFormula("Sheet1", "B1", "BESSELK(A1, A2)")
    
    // 使用BESSELY函数
    f.SetCellFormula("Sheet1", "B2", "BESSELY(A1, A2)")
    
    // 计算公式结果
    result1, _ := f.CalcCellValue("Sheet1", "B1")
    result2, _ := f.CalcCellValue("Sheet1", "B2")
    
    fmt.Printf("BESSELK结果: %s\n", result1)
    fmt.Printf("BESSELY结果: %s\n", result2)
    
    f.SaveAs("公式示例.xlsx")
}

4. 定义名称引用支持

公式计算引擎现在支持通过定义名称来引用数据范围。

package main

import (
    "fmt"
    "github.com/xuri/excelize/v2"
)

func main() {
    f := excelize.NewFile()
    
    // 设置数据
    data := []interface{}{10, 20, 30, 40, 50}
    for i, value := range data {
        cell := fmt.Sprintf("A%d", i+1)
        f.SetCellValue("Sheet1", cell, value)
    }
    
    // 定义名称
    if err := f.SetDefinedName(&excelize.DefinedName{
        Name:     "MyData",
        RefersTo: "Sheet1!$A$1:$A$5",
        Comment:  "自定义数据范围",
    }); err != nil {
        fmt.Println(err)
        return
    }
    
    // 在公式中使用定义名称
    f.SetCellFormula("Sheet1", "B1", "SUM(MyData)")
    
    // 计算公式
    result, _ := f.CalcCellValue("Sheet1", "B1")
    fmt.Printf("使用定义名称的计算结果: %s\n", result)
    
    f.SaveAs("定义名称示例.xlsx")
}

5. 时间处理改进

不再需要将时间转换为UTC时区,简化了时间值的设置。

package main

import (
    "fmt"
    "github.com/xuri/excelize/v2"
    "time"
)

func main() {
    f := excelize.NewFile()
    
    // 直接使用本地时间
    localTime := time.Now()
    f.SetCellValue("Sheet1", "A1", localTime)
    
    // 设置时间格式
    style, _ := f.NewStyle(&excelize.Style{
        NumFmt: 22, // 时间格式
    })
    f.SetCellStyle("Sheet1", "A1", "A1", style)
    
    // 读取时间值
    cellValue, _ := f.GetCellValue("Sheet1", "A1")
    fmt.Printf("单元格时间值: %s\n", cellValue)
    
    f.SaveAs("时间处理示例.xlsx")
}

这些示例展示了Excelize 2.4.1版本中一些重要新特性的使用方法。特别是并发安全性的改进使得在高并发场景下处理Excel文件更加高效可靠。

回到顶部