Files
x_admin/server/util/excel2/excel_export_2.go
2024-08-12 02:25:15 +08:00

174 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package excel2
import (
"fmt"
"net/http"
"github.com/xuri/excelize/v2"
)
type Col struct {
Name string
Key string
Width int
}
// GetExcelColumnName2 根据列数生成 Excel 列名
func GetExcelColumnName2(columnNumber int) string {
columnName := ""
for columnNumber > 0 {
remainder := (columnNumber - 1) % 26
columnName = string(rune('A'+remainder)) + columnName
columnNumber = (columnNumber - 1) / 26
}
return columnName
}
// NormalDynamicExport 导出excel
//
// 需要在传入的结构体中的字段加上tagexcel:"title:列头名称;index:列下标(从0开始);"
//
// list 要导出的数据
//
// cols 列
//
// sheet 文档
// title 标题
func NormalDynamicExport2(lists []map[string]interface{}, cols []Col, sheet string, title string) (file *excelize.File, err error) {
e := ExcelInit()
err = ExportExcel2(sheet, title, lists, cols, e)
if err != nil {
return
}
return e.F, err
}
// ExportExcel2 excel导出
func ExportExcel2(sheet, title string, lists []map[string]interface{}, cols []Col, e *Excel) (err error) {
index, _ := e.F.GetSheetIndex(sheet)
if index < 0 { // 如果sheet名称不存在
e.F.NewSheet(sheet)
}
// 构造表头
endColName, startDataRow, err := normalBuildTitle2(e, sheet, title, cols)
if err != nil {
return
}
// 构造数据行
err = normalBuildDataRow2(e, sheet, endColName, startDataRow, lists, cols)
return
}
// 构造表头endColName 最后一列的列名 startDataRow 数据行开始的行号)
func normalBuildTitle2(e *Excel, sheet, title string, cols []Col) (endColName string, startDataRow int, err error) {
var titleRowData []interface{} // 列头行
for i, colTitle := range cols {
endColName := GetExcelColumnName2(i + 1)
if colTitle.Width > 0 { // 根据给定的宽度设置列宽
_ = e.F.SetColWidth(sheet, endColName, endColName, float64(colTitle.Width))
} else {
_ = e.F.SetColWidth(sheet, endColName, endColName, float64(20)) // 默认宽度为20
}
titleRowData = append(titleRowData, colTitle.Name)
}
endColName = GetExcelColumnName2(len(titleRowData)) // 根据列数生成 Excel 列名
if title != "" {
startDataRow = 3 // 如果有title那么从第3行开始就是数据行第1行是title第2行是表头
e.F.SetCellValue(sheet, "A1", title)
e.F.MergeCell(sheet, "A1", endColName+"1") // 合并标题单元格
e.F.SetCellStyle(sheet, "A1", endColName+"1", e.TitleStyle)
e.F.SetRowHeight(sheet, 1, float64(30)) // 第一行行高
e.F.SetRowHeight(sheet, 2, float64(30)) // 第二行行高
e.F.SetCellStyle(sheet, "A2", endColName+"2", e.HeadStyle)
if err = e.F.SetSheetRow(sheet, "A2", &titleRowData); err != nil {
return
}
} else {
startDataRow = 2 // 如果没有title那么从第2行开始就是数据行第1行是表头
e.F.SetRowHeight(sheet, 1, float64(30))
e.F.SetCellStyle(sheet, "A1", endColName+"1", e.HeadStyle)
if err = e.F.SetSheetRow(sheet, "A1", &titleRowData); err != nil {
return
}
}
return
}
// 构造数据行
func normalBuildDataRow2(e *Excel, sheet, endColName string, startDataRow int, lists []map[string]interface{}, cols []Col) (err error) {
//实时写入数据
for i := 0; i < len(lists); i++ {
startCol := fmt.Sprintf("A%d", startDataRow)
endCol := fmt.Sprintf("%s%d", endColName, startDataRow)
var rowData []interface{} // 数据列
list := lists[i]
for j := 0; j < len(cols); j++ {
col := cols[j]
val := list[col.Key]
// switch val.(type) {
// default:
// v, _ := json.Marshal(list[col.Key])
// rowData = append(rowData, v)
// }
rowData = append(rowData, val)
}
// // 替换
// if dataCol.Replace != "" {
// split := strings.Split(dataCol.Replace, ",")
// for j := range split {
// s := strings.Split(split[j], "_") // 根据下划线进行分割格式需要替换的内容_替换后的内容
// value := fieldData.String()
// if strings.Contains(fieldData.Type().String(), "int") {
// value = strconv.Itoa(int(fieldData.Int()))
// } else if fieldData.Type().String() == "bool" {
// value = strconv.FormatBool(fieldData.Bool())
// } else if strings.Contains(fieldData.Type().String(), "float") {
// value = strconv.FormatFloat(fieldData.Float(), 'f', -1, 64)
// }
// if s[0] == value {
// dataCol.Value = s[1]
// }
// }
// } else {
// dataCol.Value = fieldData
// }
// if err != nil {
// return
// }
// exportRow = append(exportRow, dataCol)
// }
if startDataRow%2 == 0 {
_ = e.F.SetCellStyle(sheet, startCol, endCol, e.ContentStyle2)
} else {
_ = e.F.SetCellStyle(sheet, startCol, endCol, e.ContentStyle1)
}
_ = e.F.SetRowHeight(sheet, startDataRow, float64(25)) // 默认行高25
if err = e.F.SetSheetRow(sheet, startCol, &rowData); err != nil {
return
}
startDataRow++
}
return
}
// 下载
func DownLoadExcel2(fileName string, res http.ResponseWriter, file *excelize.File) {
// 设置响应头
res.Header().Set("Content-Type", "text/html; charset=UTF-8")
res.Header().Set("Content-Type", "application/octet-stream")
res.Header().Set("Content-Disposition", "attachment; filename="+fileName+".xlsx")
res.Header().Set("Access-Control-Expose-Headers", "Content-Disposition")
err := file.Write(res) // 写入Excel文件内容到响应体
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
}