go語言中使用excel template生成報表


最近要實現一個生成excel的報表服務,具體要實現的報表樣子大概如下(暫時忽略樣式Freezing):

blogs-p

 

功能描述

如上圖所示,要實現這樣一個報表每一個sheet中按照周去展示,每一周中顯示對應的日、周、月、未執行的服務,並且標上執行人,而且對於不同時期的版本要記錄不同的sheet

如果對應程序的角度,每個sheet中要循環周數據,每一周中對應的服務要各自循環輸出每一個項目,對於單個excel文件要循環輸出多個sheet。

循環套循環…,考慮到如果有這樣一個模板文件支持特定標識符的內嵌,然后程序可以根據這些標識符輸出對應的excel,功能就實現了。

 

功能實現

在github中發現了這樣一個repo, github.com/ivahaev/go-xlsx-templater 的go語言實現庫

 

Simple .xlsx (Excel XML document) template based document generator using handlebars.

Takes input .xlsx documents with mustache sippets in it and renders new document with snippets replaced by provided context.

Thanks to github.com/tealeg/xlsx and github.com/aymerick/raymond for useful libs

 

可以看到里邊用到了 tealeg/xlsx 和  aymerick/raymod 這兩個包,第一個是go語言實現的excel庫,第二個是對於template的解析

具體的介紹可以去這兩個包對應的repo中了解,這里就不在描述了。

 

使用方式也很簡單

1. 預加載模板

2. 渲染(拷貝)

3. 輸出文件

1 doc := xlst.New()
2 doc.ReadTemplate("./template.xlsx")
3 doc.Render(ctx) 4 doc.Save("./report.xlsx")

要實現文中開始描述的報表功能還需要修改package的源碼,主要解決的問題是

  • 當前的代碼template包不支持一個數據集合輸出多個sheet,當前支持的是按照模板文件中的sheet分別渲染。
  • 當excel模板中cell設置了文字換行和高度自動適應時,輸出的excel報表中文字會被遮蓋。
  • 不支持打印分隔符
  1 // RenderMultipleSheet 輸出多個sheet
  2 func (m *Xlst) RenderMultipleSheet(options *Options ,in ...InParam) error {
  3 	if options == nil {
  4 		options = new(Options)
  5 	}
  6 	report := xlsx.NewFile()
  7 	//TODO: 模板中只考慮單個sheet
  8 	for si, sheet := range m.file.Sheets {
  9 		for idx,item:=range in{
 10 			ctx := getCtx(item.In, si)
 11 			if item.SheetName==""{
 12 				report.AddSheet(fmt.Sprintf("Sheet%d",idx))
 13 			}else{
 14 				_,e:=report.AddSheet(item.SheetName)
 15 				if e!=nil{
 16 					fmt.Errorf("%+v",e)
 17 				}
 18 			}
 19 			l:=len(report.Sheets)
 20 			fmt.Printf("%d",l)
 21 			cloneSheet(sheet, report.Sheets[idx])
 22 			err := renderRows(report.Sheets[idx], sheet.Rows, ctx, options)
 23 			if err != nil {
 24 				return err
 25 			}
 26 
 27 			for _, col := range sheet.Cols {
 28 				report.Sheets[idx].Cols = append(report.Sheets[idx].Cols, col)
 29 			}
 30 		}
 31 
 32 	}
 33 	m.report = report
 34 	return nil
 35 }
  1 //xlst
  2 // 高度自適應修改
  3 //to.SetHeight(from.Height)

打印分隔符的支持,我參考了 360EntSecGroup-Skylar/excelize包的實現(對應 InsertBreakPage),將打印分隔符相關的struct xml字段和方法遷移到了 tealeg/xlsx 庫中,東拼西湊的感覺Sad smile

 

  1 type Sheet struct {
  2 	Name        string
  3 	File        *File
  4 	Rows        []*Row
  5 	Cols        []*Col
  6 	MaxRow      int
  7 	MaxCol      int
  8 	Hidden      bool
  9 	Selected    bool
 10 	SheetViews  []SheetView
 11 	SheetFormat SheetFormat
 12 	AutoFilter  *AutoFilter
 13 	// 加入 分頁符
 14 	RowBreaks       *XlsxBreaks
 15 	ColBreaks       *XlsxBreaks
 16 }

 

我的模板文件:

goexcel

 

結束語

 

開源社區有很多優秀的package,可能某個特定的package對自己所需要的功能實現的還不夠完整,那就自己嘗試着去改吧,這個過程也有助於自己去熟悉go語言。

 

 

For what it's worth,It's never too late.

 

 

轉載請標明出自:go語言中使用excel template生成報表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM