// ExportTaskDetailToExcel 将 TaskDetail 结果导出为 Excel 并返回文件流(可用于 HTTP 下载)
func (impl *nearStatServiceImpl) ExportTaskDetailToExcel(param *req.NearInstanceTaskDetailReq) (io.ReadSeeker, string, error) {
// 先获取原始数据
result, svcErr := impl.TaskDetail(param)
if svcErr != nil {
return nil, "", fmt.Errorf("failed to load task detail: %v", svcErr)
}
// 创建 Excel 文件
f := excelize.NewFile()
defer f.Close()
// 创建工作表
sheetName := "SQL指纹统计"
index, _ := f.NewSheet(sheetName)
f.SetActiveSheet(index)
// 设置标题行(可根据 res.NearSqlFpStat 字段调整)
headers := []string{
"SQL指纹", "总执行次数", "总执行时间(μs)", "平均执行时间(μs)", "最大执行时间(μs)", "最小执行时间(μs)",
}
headerCols := []string{"A", "B", "C", "D", "E", "F"}
for i, col := range headerCols {
cell := fmt.Sprintf("%s1", col)
f.SetCellValue(sheetName, cell, headers[i])
}
// 填充数据
for i, item := range result.SqlFpStatList {
row := i + 2 // 第二行开始写入
f.SetCellValue(sheetName, fmt.Sprintf("A%d", row), item.SqlFp)
f.SetCellValue(sheetName, fmt.Sprintf("B%d", row), item.TotalNum)
f.SetCellValue(sheetName, fmt.Sprintf("C%d", row), item.TotalExeTime)
f.SetCellValue(sheetName, fmt.Sprintf("D%d", row), item.AvgExeTime)
f.SetCellValue(sheetName, fmt.Sprintf("E%d", row), item.MaxExeTime)
f.SetCellValue(sheetName, fmt.Sprintf("F%d", row), item.MinExeTime)
}
// 可选:自动列宽(Excelize 不直接支持,需估算)
_ = f.SetColWidth(sheetName, "A", "A", 50) // SQL指纹列宽一些
_ = f.SetColWidth(sheetName, "B", "F", 15)
// 创建加粗样式的 Style ID
boldStyle, err := f.NewStyle(&excelize.Style{
Font: &excelize.Font{Bold: true},
})
if err != nil {
logger.Errorf("创建加粗样式失败: %v", err)
return nil, "", err
}
// 使用 style ID 设置单元格样式
err = f.SetCellStyle(sheetName, "A1", fmt.Sprintf("%s1", headerCols[len(headerCols)-1]), boldStyle)
if err != nil {
logger.Errorf("设置标题行加粗失败: %v", err)
return nil, "", err
}
// 创建一个 buffer 来接收 Excel 数据
var buf bytes.Buffer
// 使用 Write(io.Writer) 方式写入 buffer
err = f.Write(&buf)
if err != nil {
return nil, "", fmt.Errorf("failed to write excel data: %v", err)
}
// 从 buffer 获取字节流
fileBytes := buf.Bytes()
// 使用 bytes.NewReader 实现 io.ReadSeeker
reader := bytes.NewReader(fileBytes)
// 构造文件名(可包含参数信息)
fileName := fmt.Sprintf("延时分析任务_%s_慢日志统计_%d.xlsx", param.Id, time.Now().Unix())
return reader, fileName, nil
}
最新发布