gitea/services/export/excel.go

95 lines
2.2 KiB
Go

// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package export
import (
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/services/context"
"github.com/xuri/excelize/v2"
)
func IssuesToExcel(ctx *context.Context, issues issues_model.IssueList) *excelize.File {
f := excelize.NewFile()
sw, err := f.NewStreamWriter("Sheet1")
if err != nil {
log.Error("cannot open stream writer for Sheet1: %v", err)
return f
}
// print headers
cell, err := excelize.CoordinatesToCellName(1, 1)
if err != nil {
log.Error("cannot get first cell: %v", err)
return f
}
err = sw.SetRow(cell, []any{
excelize.Cell{Value: "ID"},
excelize.Cell{Value: "Title"},
excelize.Cell{Value: "Status"},
excelize.Cell{Value: "Assignee(s)"},
excelize.Cell{Value: "Label(s)"},
excelize.Cell{Value: "Created At"},
})
if err != nil {
log.Error("cannot SetRow for header: %v", err)
return f
}
// built-in format ID 22 ("m/d/yy h:mm")
datetimeStyleID, err := f.NewStyle(&excelize.Style{NumFmt: 22})
if err != nil {
log.Error("cannot set new style NumFmt: %v", err)
return f
}
for i, issue := range issues {
assignees := ""
if err := issue.LoadAssignees(ctx); err == nil {
if len(issue.Assignees) > 0 {
for _, assignee := range issue.Assignees {
if assignees != "" {
assignees += ", "
}
if assignee.FullName != "" {
assignees += assignee.FullName
} else {
assignees += assignee.Name
}
}
}
}
labels := ""
if err := issue.LoadLabels(ctx); err == nil {
if len(issue.Labels) > 0 {
for _, label := range issue.Labels {
if labels != "" {
labels += ", "
}
labels += label.Name
}
}
}
cell, _ := excelize.CoordinatesToCellName(1, i+2)
err = sw.SetRow(cell, []any{
excelize.Cell{Value: issue.Index},
excelize.Cell{Value: issue.Title},
excelize.Cell{Value: issue.State()},
excelize.Cell{Value: assignees},
excelize.Cell{Value: labels},
excelize.Cell{StyleID: datetimeStyleID, Value: issue.CreatedUnix.AsTime()},
})
if err != nil {
log.Error("cannot SetRow: %v", err)
return f
}
}
sw.Flush()
return f
}