132 lines
4.3 KiB
Go
132 lines
4.3 KiB
Go
package excel
|
|
|
|
import (
|
|
"electricity_bill_calc/logger"
|
|
"electricity_bill_calc/model"
|
|
"electricity_bill_calc/tools"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/xuri/excelize/v2"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var meterReadingsRecognizers = []*ColumnRecognizer{
|
|
{Pattern: [][]string{{"表", "表计"}, {"编号"}}, Tag: "code", MatchIndex: -1, MustFill: true},
|
|
{Pattern: [][]string{{"抄表", "结束"}, {"时间", "日期"}}, Tag: "readAt", MatchIndex: -1, MustFill: true},
|
|
{Pattern: [][]string{{"用电", "有功", "表底", "底数"}, {"总", "量"}}, Tag: "overall", MatchIndex: -1, MustFill: true},
|
|
{Pattern: [][]string{{"有功", "表底", "底数"}, {"尖"}}, Tag: "critical", MatchIndex: -1},
|
|
{Pattern: [][]string{{"有功", "表底", "底数"}, {"峰"}}, Tag: "peak", MatchIndex: -1},
|
|
{Pattern: [][]string{{"有功", "表底", "底数"}, {"谷"}}, Tag: "valley", MatchIndex: -1},
|
|
}
|
|
|
|
func NewMeterReadingsExcelAnalyzer(file io.Reader) (*ExcelAnalyzer[model.ReadingImportRow], error) {
|
|
return NewExcelAnalyzer[model.ReadingImportRow](file, meterReadingsRecognizers)
|
|
}
|
|
|
|
type MeterReadingsExcelTemplateGenerator struct {
|
|
file *excelize.File
|
|
log *zap.Logger
|
|
}
|
|
|
|
func NewMeterReadingsExcelTemplateGenerator() *MeterReadingsExcelTemplateGenerator {
|
|
return &MeterReadingsExcelTemplateGenerator{
|
|
file: excelize.NewFile(),
|
|
log: logger.Named("Excel", "MeterReadings"),
|
|
}
|
|
}
|
|
|
|
func (MeterReadingsExcelTemplateGenerator) titles() *[]interface{} {
|
|
return &[]interface{}{
|
|
"抄表序号",
|
|
"抄表时间",
|
|
"表计编号",
|
|
"表计名称",
|
|
"商户名称",
|
|
"倍率",
|
|
"有功(总)",
|
|
"有功(尖)",
|
|
"有功(峰)",
|
|
"有功(谷)",
|
|
}
|
|
}
|
|
|
|
func (g MeterReadingsExcelTemplateGenerator) Close() {
|
|
g.file.Close()
|
|
}
|
|
|
|
func (g MeterReadingsExcelTemplateGenerator) WriteTo(w io.Writer) (int64, error) {
|
|
return g.file.WriteTo(w)
|
|
}
|
|
|
|
func (g MeterReadingsExcelTemplateGenerator) WriteTemplateData(meters []*model.SimpleMeterDocument) error {
|
|
var err error
|
|
defaultSheet := g.file.GetSheetName(0)
|
|
g.log.Debug("选定默认输出表格", zap.String("sheet", defaultSheet))
|
|
err = g.file.SetColWidth(defaultSheet, "A", "E", 30)
|
|
if err != nil {
|
|
g.log.Error("未能设定长型单元格的宽度。", zap.Error(err))
|
|
return fmt.Errorf("未能设定长型单元格的宽度,%w", err)
|
|
}
|
|
err = g.file.SetColWidth(defaultSheet, "F", "F", 10)
|
|
if err != nil {
|
|
g.log.Error("未能设定倍率单元格的宽度。", zap.Error(err))
|
|
return fmt.Errorf("未能设定倍率单元格的宽度,%w", err)
|
|
}
|
|
err = g.file.SetColWidth(defaultSheet, "G", "J", 20)
|
|
if err != nil {
|
|
g.log.Error("未能设定短型单元格的宽度。", zap.Error(err))
|
|
return fmt.Errorf("未能设定短型单元格的宽度,%w", err)
|
|
}
|
|
err = g.file.SetSheetRow(defaultSheet, "A1", g.titles())
|
|
if err != nil {
|
|
g.log.Error("未能输出模板标题。", zap.Error(err))
|
|
return fmt.Errorf("未能输出模板标题,%w", err)
|
|
}
|
|
err = g.file.SetRowHeight(defaultSheet, 1, 30)
|
|
if err != nil {
|
|
g.log.Error("未能设定标题行的高度。", zap.Error(err))
|
|
return fmt.Errorf("未能设定标题行的高度,%w", err)
|
|
}
|
|
|
|
dateTimeExp := "yyyy-mm-dd hh:mm"
|
|
dateTimeColStyle, err := g.file.NewStyle(&excelize.Style{
|
|
CustomNumFmt: &dateTimeExp,
|
|
})
|
|
if err != nil {
|
|
g.log.Error("未能创建日期时间格式。", zap.Error(err))
|
|
return fmt.Errorf("未能创建日期时间格式,%w", err)
|
|
}
|
|
endCellCoord, _ := excelize.CoordinatesToCellName(2, len(meters)+1)
|
|
g.file.SetCellStyle(defaultSheet, "B2", endCellCoord, dateTimeColStyle)
|
|
|
|
numExp := "0.0000"
|
|
numColStyle, err := g.file.NewStyle(&excelize.Style{
|
|
CustomNumFmt: &numExp,
|
|
})
|
|
if err != nil {
|
|
g.log.Error("未能创建抄表数字格式。", zap.Error(err))
|
|
return fmt.Errorf("未能创建抄表数字格式,%w", err)
|
|
}
|
|
endCellCoord, _ = excelize.CoordinatesToCellName(9, len(meters)+1)
|
|
g.file.SetCellStyle(defaultSheet, "F2", endCellCoord, numColStyle)
|
|
|
|
for i, meter := range meters {
|
|
cellCoord, _ := excelize.CoordinatesToCellName(1, i+2)
|
|
ratio, _ := meter.Ratio.Float64()
|
|
if err := g.file.SetSheetRow(defaultSheet, cellCoord, &[]interface{}{
|
|
meter.Seq,
|
|
"",
|
|
meter.Code,
|
|
tools.DefaultTo(meter.Address, ""),
|
|
tools.DefaultTo(meter.TenementName, ""),
|
|
ratio,
|
|
}); err != nil {
|
|
g.log.Error("向模板写入数据出现错误。", zap.Error(err))
|
|
return fmt.Errorf("向模板写入数据出现错误,%w", err)
|
|
}
|
|
}
|
|
|
|
return err
|
|
}
|