作者

项目地址

原理

经查看xlsx的底层xml,发现公式可以使用<f></f>
标签输出,eg.<f>HYPERLINK("https://www.baidu.com","百度")</f>
,利用这点改造excelize按行流式输出函数,使其支持输出<f></f>标签

核心代码

func writeMyCell(buf *myBufferedWriter, c myXlsxC) {
	...
	/*
	 * 新增公式标签输出
	 */
	if c.MyF != "" {
		buf.WriteString(`<f>`)
		xml.EscapeText(buf, []byte(c.MyF))
		buf.WriteString(`</f>`)
	}
	...
}

示例

package main
 
import (
	xstream "gitee.com/sqxwww/xexcelize/stream"
	"github.com/360EntSecGroup-Skylar/excelize/v2"
)
 
const (
	rowNum = 1e5 //导出行数
	colNum = 10  //导出列数
)
 
func main() {
	file := excelize.NewFile()
	sw, err := file.NewStreamWriter("Sheet1")
	if err != nil {
		panic(err)
	}
	//利用excelize原生流创建自定义流
	mySw := xstream.NewMyStreamWriter(sw)
	//创建下划线样式
	underline, err := file.NewStyle(`{"font":{"color":"#1265BE","underline":"single"}}`)
	for rowID := 1; rowID <= rowNum; rowID++ {
		row := make([]interface{}, colNum)
		for colID := 0; colID < colNum; colID++ {
			//创建单元格实例,样式为下划线,公式为HYPERLINK
			row[colID] = xstream.MyCell{
				StyleID: underline,
				Formula: `HYPERLINK("https://www.baidu.com","度娘")`,
			}
		}
		cell, _ := excelize.CoordinatesToCellName(1, rowID)
		//使用自定义流按行写入
		if err = mySw.SetRow(cell, row); err != nil {
			panic(err)
		}
	}
	if err = mySw.Flush(); err != nil {
		panic(err)
	}
	file.SaveAs("example_url.xlsx")
}

效果截图