如何使用 Go 和 Excelize 构建电子表格

目录
  • 前言
  • 生成费用报告
  • 创建工作表
  • 添加数据和创建样式
  • 导出为 CSV
  • 结论

前言

分析任何规模的数据的重要性怎么强调都不为过。 我们日常生活的几乎每个部分都是数据驱动的,作为开发人员,在构建任何合理大小的应用程序时,首要考虑的因素之一是使用什么数据库以及如何构建数据。

但是,它不仅限于存储数据,您还需要通过提取并以任何非技术人员都能理解的格式呈现这些数据来理解这些数据。 例如,电子商务企业每天都会产生大量数据,这意味着我们需要跟踪产品库存、月收入、财务报表等信息。 目前,有许多服务提供这些类型的解决方案,但快速提取和呈现数据的最简单方法之一是生成电子表格或 CSV 文件。

在本文中,我们将探索如何在 Go 中创建电子表格,方法是构建一个简单的费用报告并使用 Excelize 库将其导出为 CSV 格式。 中找到本教程的完整代码 您可以在 GitHub 存储库 。 让我们开始吧!

  • 生成费用报告
  • 创建工作表
  • 添加数据和创建样式
  • 保存工作表
  • 导出为 CSV

生成费用报告

费用报告是一份详细的清单,尽可能详细地显示公司在一段时间内的支出。 我们将构建一个类似于下图中的报告:

创建工作表

要开始使用,请确保您已安装 Go ≥v1.15 并创建一个新的项目文件夹。

在项目目录中,创建一个 main.go文件并使用以下代码初始化 Go 模块:

$ mkdir <project-name>
$ cd <project-name>
$ touch main.go
$ go mod init github.com/<your-username>/<project-name>

The main.go file is the entry point of our Go application, and we use the generated go.mod file for dependency management. Next, install the Excelize library by running the command below:

$ go get github.com/xuri/excelize/v2

Excelize is a Go library with no dependencies that provides primitives for reading and writing to XLSX files and other supported spreadsheet file formats. In your main.go file, import Excelize, create a new file, create a new worksheet, and set the active sheet to the worksheet you just created:

package main
import "github.com/xuri/excelize/v2"
const (
   SheetName = "Expense Report"
)
func main() {
   var err error
   f := excelize.NewFile()
   index := f.NewSheet("Sheet1")
   f.SetActiveSheet(index)
   f.SetSheetName("Sheet1", SheetName)
}

添加数据和创建样式

创建工作表后,我们可以开始构建报告。 首先,我们将设置一些尺寸以适应我们想要的结构,如下图所示。

将以下代码块添加到您的 main功能:

//main.go
//...
   err = f.SetColWidth(SheetName, "A", "A", 6)
   err = f.SetColWidth(SheetName, "H", "H", 6)
   err = f.SetColWidth(SheetName, "B", "B", 12)
   err = f.SetColWidth(SheetName, "C", "C", 16)
   err = f.SetColWidth(SheetName, "D", "D", 13)
   err = f.SetColWidth(SheetName, "E", "E", 15)
   err = f.SetColWidth(SheetName, "F", "F", 22)
   err = f.SetColWidth(SheetName, "G", "G", 13)

我们只需要列 A至 G对于报告,所以我们使用 SetColWidth调整列的宽度以满足我们的要求。 你会注意到我们已经定义了一个 error变量到顶部 main函数,我们只是将这些函数返回的任何错误分配给它。 理想情况下,您应该正确处理每个错误,因为它在 Go 中是惯用的,但保持代码最少也是可以的。

Over 200k developers use LogRocket to create better digital experiences Learn more →

报告的第一部分包含静态信息,因此我们将对其进行硬编码。 将以下代码块添加到您的 main 函数中:

//main.go
//...
   err = f.SetRowHeight(SheetName, 1, 12)
   err = f.MergeCell(SheetName, "A1", "H1")
​
   err = f.SetRowHeight(SheetName, 2, 25)
   err = f.MergeCell(SheetName, "B2", "D2")
​
   style, err := f.NewStyle(&excelize.Style{Font: &excelize.Font{Size: 20, Color: "6d64e8"}})
   err = f.SetCellStyle(SheetName, "B2", "D2", style)
   err = f.SetSheetRow(SheetName, "B2", &[]interface{}{"Gigashots Inc."})
   err = f.MergeCell(SheetName, "B3", "D3")
   err = f.SetSheetRow(SheetName, "B3", &[]interface{}{"3154 N Richardt Ave"})
​
   err = f.MergeCell(SheetName, "B4", "D4")
   err = f.SetSheetRow(SheetName, "B4", &[]interface{}{"Indianapolis, IN 46276"})
​
   style, err = f.NewStyle(&excelize.Style{Font: &excelize.Font{Color: "666666"}})
   err = f.MergeCell(SheetName, "B5", "D5")
   err = f.SetCellStyle(SheetName, "B5", "D5", style)
   err = f.SetSheetRow(SheetName, "B5", &[]interface{}{"(317) 854-0398"})
​
   style, err = f.NewStyle(&excelize.Style{Font: &excelize.Font{Size: 32, Color: "2B4492", Bold: true}})
   err = f.MergeCell(SheetName, "B7", "G7")
   err = f.SetCellStyle(SheetName, "B7", "G7", style)
   err = f.SetSheetRow(SheetName, "B7", &[]interface{}{"Expense Report"})
​
   style, err = f.NewStyle(&excelize.Style{Font: &excelize.Font{Size: 13, Color: "E25184", Bold: true}})
   err = f.MergeCell(SheetName, "B8", "C8")
   err = f.SetCellStyle(SheetName, "B8", "C8", style)
   err = f.SetSheetRow(SheetName, "B8", &[]interface{}{"09/04/00 - 09/05/00"})
​
   style, err = f.NewStyle(&excelize.Style{Font: &excelize.Font{Size: 13, Bold: true}})
   err = f.SetCellStyle(SheetName, "B10", "G10", style)
   err = f.SetSheetRow(SheetName, "B10", &[]interface{}{"Name", "", "Employee ID", "", "Department"})
   err = f.MergeCell(SheetName, "B10", "C10")
   err = f.MergeCell(SheetName, "D10", "E10")
   err = f.MergeCell(SheetName, "F10", "G10")
​
   style, err = f.NewStyle(&excelize.Style{Font: &excelize.Font{Color: "666666"}})
   err = f.SetCellStyle(SheetName, "B11", "G11", style)
   err = f.SetSheetRow(SheetName, "B11", &[]interface{}{"John Doe", "", "#1B800XR", "", "Brand & Marketing"})
   err = f.MergeCell(SheetName, "B11", "C11")
   err = f.MergeCell(SheetName, "D11", "E11")
   err = f.MergeCell(SheetName, "F11", "G11")
​
   style, err = f.NewStyle(&excelize.Style{Font: &excelize.Font{Size: 13, Bold: true}})
   err = f.SetCellStyle(SheetName, "B13", "G13", style)
   err = f.SetSheetRow(SheetName, "B13", &[]interface{}{"Manager", "", "Purpose"})
   err = f.MergeCell(SheetName, "B13", "C13")
   err = f.MergeCell(SheetName, "D13", "E13")
​
   style, err = f.NewStyle(&excelize.Style{Font: &excelize.Font{Color: "666666"}})
   err = f.SetCellStyle(SheetName, "B14", "G14", style)
   err = f.SetSheetRow(SheetName, "B14", &[]interface{}{"Jane Doe", "", "Brand Campaign"})
   err = f.MergeCell(SheetName, "B14", "C14")
   err = f.MergeCell(SheetName, "D14", "E14")

这段代码中有很多内容,所以让我们分解一下。

如前所述,Excelize 提供了一组原始函数来操作电子表格。 您需要的每个功能只需要在文件对象上调用一个方法,该方法接受一些参数。

在这种情况下,我们使用了五种主要方法:

  • SetRowHeight
  • MergeCell
  • NewStyle
  • SetCellStyle
  • SetSheetRow

SetRowHeight调整给定行的高度,以及 MergeCell将一行中的多个单元格合并为一个单元格。 要编写样式,我们可以使用 excelize.Stylestruct,它提供了定义自定义样式所需的属性。 这 NewStyle方法只是采用 Style对象并返回表示样式的索引。

定义您的自定义样式后,我们可以使用 SetCellStyle将样式应用于单个单元格或一系列单元格。 我们用 SetSheetRow将数据添加到单行中的一个单元格或一系列单元格。 它接受一个接口切片,它是任何原始数据类型的容器。 切片是位置的,每个元素将从提供的轴开始放置在相应的单元格中。 因此,在合并多个单元格的某些情况下,我们使用了空字符串。

报告的第二部分是一个包含任意长度的动态数据的表格,这意味着我们不能像以前那样只定义每一行的内容。 表中表示的数据遵循定义的结构,因此我们可以循环传入数据并动态创建每一行。

让我们定义一些代表费用列表的任意数据。

在您的顶部 main.go文件,在 main函数,添加以下变量:

//main.go
//...
var (
   expenseData = [][]interface{}{
      {"2022-04-10", "Flight", "Trip to San Fransisco", "", "", "$3,462.00"},
      {"2022-04-10", "Hotel", "Trip to San Fransisco", "", "", "$1,280.00"},
      {"2022-04-12", "Swags", "App launch", "", "", "$862.00"},
      {"2022-03-15", "Marketing", "App launch", "", "", "$7,520.00"},
      {"2022-04-11", "Event hall", "App launch", "", "", "$2,080.00"},
   }
)
//...

现在,将以下代码块添加到您的 main 函数中:

//main.go
//...
   style, err = f.NewStyle(&excelize.Style{
      Font:      &excelize.Font{Size: 13, Bold: true, Color: "2B4492"},
      Alignment: &excelize.Alignment{Vertical: "center"},
   })
   err = f.SetCellStyle(SheetName, "B17", "G17", style)
   err = f.SetSheetRow(SheetName, "B17", &[]interface{}{"Date", "Category", "Description", "", "Notes", "Amount"})
   err = f.MergeCell(SheetName, "D17", "E17")
   err = f.SetRowHeight(SheetName, 17, 32)
​
   startRow := 18
   for i := startRow; i < (len(expenseData) + startRow); i++ {
      var fill string
      if i%2 == 0 {
         fill = "F3F3F3"
      } else {
         fill = "FFFFFF"
      }
      style, err = f.NewStyle(&excelize.Style{
         Fill:      excelize.Fill{Type: "pattern", Pattern: 1, Color: []string{fill}},
         Font:      &excelize.Font{Color: "666666"},
         Alignment: &excelize.Alignment{Vertical: "center"},
      })
      err = f.SetCellStyle(SheetName, fmt.Sprintf("B%d", i), fmt.Sprintf("G%d", i), style)
      err = f.SetSheetRow(SheetName, fmt.Sprintf("B%d", i), &expenseData[i-18])
      err = f.SetCellRichText(SheetName, fmt.Sprintf("C%d", i), []excelize.RichTextRun{
         {Text: expenseData\[i-18\][1].(string), Font: &excelize.Font{Bold: true}},
      })
​
      err = f.MergeCell(SheetName, fmt.Sprintf("D%d", i), fmt.Sprintf("E%d", i))
      err = f.SetRowHeight(SheetName, i, 18)
   }

我们仍然使用相同的方法来组合样式和添加数据。 但是,我们正在循环 expenseData列出并将每个项目添加到当前行。 我们开始循环 18,这是电子表格中的当前行。 为了使表格的行更加清晰易读,我们通过使用 modulo手术。

导出为 CSV

到目前为止,我们已经探索了使用 XLSX 文件,但是,还有其他格式适合呈现这种数据。 CSV 文件是一个文本文件,其中包含由逗号分隔的数据行,主要用于导入和导出数据。

考虑一种情况,我们希望将费用报告中的表存储在某个自托管数据库中。 我们可以将这个表格提取为 CSV 格式,然后通过几个步骤将其导入数据库。

首先,在主函数之外创建一个名为 generateCSV并在下面添加代码块:

//main.go
//...
type Axis struct {
   row int
   col string
}
​
func generateCSV(f *excelize.File, start, end Axis) error {
   var data [][]string
​
   for i := start.row; i <= end.row; i++ {
      row := []string{}
      for j := []rune(start.col)[0]; j <= []rune(end.col)[0]; j++ {
         value, err := f.GetCellValue(SheetName, fmt.Sprintf("%s%d", string(j), i), excelize.Options{})
         if err != nil {
            return err
         }
         row = append(row, value)
      }
      data = append(data, row)
   }
​
   file, err := os.Create("expenses.csv")
   if err != nil {
      return err
   }
   defer f.Close()
​
   writer := csv.NewWriter(file)
   return writer.WriteAll(data)
}

这 generateCSV函数接受一个 excelize.File类型、起始轴和结束轴。 轴只是构成单元格的行和列的组合。 我们循环遍历每一行,对于每一行,我们循环遍历开始轴和结束轴边界内的每一列。

然后我们使用 f.GetCellValue提取每个单元格的当前值。 因为列表示为字母字符串,所以我们将它们转换为符文以获取底层的 unicode 十进制。 最后,我们将提取的数据保存到 .csv文件 使用标准库中的 CSV 包 。

我们可以在保存工作表并传递文件句柄后调用此函数。

在你的 main函数,添加以下代码块:

//main.go
///...
   err = f.SaveAs("expense-report.xlsx")
   err = generateCSV(f, Axis{17, "B"}, Axis{22, "G"})
​
   if err != nil {
      log.Fatal(err)
   }

我们提供了我们之前为工作表创建的文件和表示表格范围的轴。

如果你运行 main.go文件,您应该会看到生成的 XLSX 文件和 CSV 文件:

$ go run main.go

结论

以电子表格兼容的格式呈现数据有很多用例,包括分析、转换和验证。 在本文中,我们学习了如何使用 Go 和 Excelize 包通过生成费用报告来处理电子表格。

当您考虑 Excelize 开箱即用的其他功能时,我们只是触及了皮毛。 您可以添加图像、创建图表、迷你图、形状、数据透视表等。 我希望你学到了一些新的东西,如果你有任何问题,请发表评论。 快乐编码!

LogRocket 主动显示和诊断您的应用程序和网站中最重要的问题

成千上万的工程和产品团队使用 LogRocket 来减少了解技术和可用性问题的根本原因所需的时间。 使用 LogRocket,您将减少与客户来回对话的时间,并消除无休止的故障排除过程。 LogRocket 让您可以花更多时间构建新事物,而减少修复错误的时间。

到此这篇关于如何使用 Go 和 Excelize 构建电子表格的文章就介绍到这了,更多相关Go 与 Excelize 构建表格内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Go Excelize API源码解析GetSheetFormatPr使用示例

    目录 一.Go-Excelize简介 二.GetSheetFormatPr 一.Go-Excelize简介 Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准. 可以使用它来读取.写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档. 支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式,高度兼容带有样式.图片(表).透视表.切片器等复杂组

  • Go Excelize API源码阅读GetPageLayout及SetPageMargins

    目录 一.Go-Excelize简介 二. GetPageLayout 三.SetPageMargins 一.Go-Excelize简介 Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准. 可以使用它来读取.写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档. 支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式,高度兼容带有样式.图片

  • Go Excelize API源码解读GetSheetViewOptions与SetPageLayout

    目录 一.Go-Excelize简介 二. GetSheetViewOptions 三. SetPageLayout 一.Go-Excelize简介 Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准. 可以使用它来读取.写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档. 支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式,高度兼容带

  • Go Excelize API源码阅读SetSheetViewOptions示例解析

    目录 一.Go-Excelize简介 二. SetSheetViewOptions 一.Go-Excelize简介 Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准. 可以使用它来读取.写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档. 支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式,高度兼容带有样式.图片(表).透视表.切片器

  • Go Excelize API源码阅读Close及NewSheet方法示例解析

    目录 一.Go-Excelize简介 二.Close() 三.NewSheet() 一.Go-Excelize简介 Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准.可以使用它来读取.写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档. 支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式,高度兼容带有样式.图片(表).透视表.切片器等

  • 如何使用 Go 和 Excelize 构建电子表格

    目录 前言 生成费用报告 创建工作表 添加数据和创建样式 导出为 CSV 结论 前言 分析任何规模的数据的重要性怎么强调都不为过. 我们日常生活的几乎每个部分都是数据驱动的,作为开发人员,在构建任何合理大小的应用程序时,首要考虑的因素之一是使用什么数据库以及如何构建数据. 但是,它不仅限于存储数据,您还需要通过提取并以任何非技术人员都能理解的格式呈现这些数据来理解这些数据. 例如,电子商务企业每天都会产生大量数据,这意味着我们需要跟踪产品库存.月收入.财务报表等信息. 目前,有许多服务提供这些类

  • 分析Python中解析构建数据知识

    Python 可以通过各种库去解析我们常见的数据.其中 csv 文件以纯文本形式存储表格数据,以某字符作为分隔值,通常为逗号:xml 可拓展标记语言,很像超文本标记语言 Html ,但主要对文档和数据进行结构化处理,被用来传输数据:json 作为一种轻量级数据交换格式,比 xml 更小巧但描述能力却不差,其本质是特定格式的字符串:Microsoft Excel 是电子表格,可进行各种数据的处理.统计分析和辅助决策操作,其数据格式为 xls.xlsx.接下来主要介绍通过 Python 简单解析构建

  • 使用 laravel sms 构建短信验证码发送校验功能

    laravel 实现短信验证码功能,搜索资料发现比较流行的有两个包: 一个是laravel sms 地址  https://github.com/toplan/laravel-sms 一个是easy sms 地址https://github.com/overtrue/easy-sms, 项目中需要实现一个发送和验证短信验证码的功能.以前的办法稍显繁琐.经高人指点,发现可以用 laravel-sms 这个包替代.且配置和使用简单易学.故有了这篇示例. 本例使用了Laravel 5.5. Api S

  • 前端构建 Less入门(CSS预处理器)

    Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量.混合(mixin).函数等功能,让 CSS 更易维护.方便制作主题.扩充. Less 可以运行在 Node.浏览器和 Rhino 平台上.网上有很多第三方工具帮助你编译 Less 源码. 一.前言 说到前端构建怎能缺少CSS预处理器呢!其实CSS的预处理器有很多啦,比较出名的有Scss.Sass.Stylus和Less.(最近还听说出现了Autoprefixer等CSS后处理器,可参考@一丝的PPT) 众多CSS预处理

  • 基于Spring + Spring MVC + Mybatis 高性能web构建实例详解

    一直想写这篇文章,前段时间痴迷于JavaScript.NodeJs.AngularJS,做了大量的研究,对前后端交互有了更深层次的认识. 今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂. 用最合适的技术去实现,并不断追求最佳实践.这就是架构之道. 希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法. 源码地址:https://github.com/Eliteams/quick4j 点击打开 源码地址:https://gi

随机推荐