262 lines
5.1 KiB
Go
262 lines
5.1 KiB
Go
package services
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/xuri/excelize/v2"
|
|
)
|
|
|
|
type ExcelService struct{}
|
|
|
|
func NewExcelService() *ExcelService {
|
|
return &ExcelService{}
|
|
}
|
|
|
|
type ExcelInfo struct {
|
|
Sheets []string `json:"sheets"`
|
|
SheetCount int `json:"sheetCount"`
|
|
FilePath string `json:"filePath"`
|
|
Size int64 `json:"size"`
|
|
}
|
|
|
|
type SheetData struct {
|
|
Name string `json:"name"`
|
|
Rows int `json:"rows"`
|
|
Columns int `json:"columns"`
|
|
Data [][]string `json:"data"`
|
|
}
|
|
|
|
func (s *ExcelService) GetExcelInfo(filePath string) (*ExcelInfo, error) {
|
|
f, err := excelize.OpenFile(filePath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("打开Excel文件失败: %v", err)
|
|
}
|
|
defer f.Close()
|
|
|
|
fileInfo, err := os.Stat(filePath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("获取文件信息失败: %v", err)
|
|
}
|
|
|
|
sheets := f.GetSheetList()
|
|
|
|
return &ExcelInfo{
|
|
Sheets: sheets,
|
|
SheetCount: len(sheets),
|
|
FilePath: filePath,
|
|
Size: fileInfo.Size(),
|
|
}, nil
|
|
}
|
|
|
|
func (s *ExcelService) GetSheetData(filePath, sheetName string) (*SheetData, error) {
|
|
f, err := excelize.OpenFile(filePath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("打开Excel文件失败: %v", err)
|
|
}
|
|
defer f.Close()
|
|
|
|
if sheetName == "" {
|
|
sheets := f.GetSheetList()
|
|
if len(sheets) == 0 {
|
|
return nil, fmt.Errorf("工作簿中没有工作表")
|
|
}
|
|
sheetName = sheets[0]
|
|
}
|
|
|
|
rows, err := f.GetRows(sheetName)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("读取工作表失败: %v", err)
|
|
}
|
|
|
|
maxCols := 0
|
|
for _, row := range rows {
|
|
if len(row) > maxCols {
|
|
maxCols = len(row)
|
|
}
|
|
}
|
|
|
|
return &SheetData{
|
|
Name: sheetName,
|
|
Rows: len(rows),
|
|
Columns: maxCols,
|
|
Data: rows,
|
|
}, nil
|
|
}
|
|
|
|
func (s *ExcelService) ConvertToCSV(inputPath, outputPath string) error {
|
|
if outputPath == "" {
|
|
outputPath = ChangeExtension(inputPath, ".csv")
|
|
}
|
|
|
|
f, err := excelize.OpenFile(inputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("打开Excel文件失败: %v", err)
|
|
}
|
|
defer f.Close()
|
|
|
|
sheets := f.GetSheetList()
|
|
if len(sheets) == 0 {
|
|
return fmt.Errorf("工作簿中没有工作表")
|
|
}
|
|
|
|
rows, err := f.GetRows(sheets[0])
|
|
if err != nil {
|
|
return fmt.Errorf("读取工作表失败: %v", err)
|
|
}
|
|
|
|
outFile, err := os.Create(outputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("创建输出文件失败: %v", err)
|
|
}
|
|
defer outFile.Close()
|
|
|
|
for _, row := range rows {
|
|
line := ""
|
|
for i, cell := range row {
|
|
if i > 0 {
|
|
line += ","
|
|
}
|
|
if containsComma(cell) {
|
|
line += "\"" + cell + "\""
|
|
} else {
|
|
line += cell
|
|
}
|
|
}
|
|
_, err := outFile.WriteString(line + "\n")
|
|
if err != nil {
|
|
return fmt.Errorf("写入CSV失败: %v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *ExcelService) ConvertToJSON(inputPath, outputPath string) error {
|
|
if outputPath == "" {
|
|
outputPath = ChangeExtension(inputPath, ".json")
|
|
}
|
|
|
|
f, err := excelize.OpenFile(inputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("打开Excel文件失败: %v", err)
|
|
}
|
|
defer f.Close()
|
|
|
|
sheets := f.GetSheetList()
|
|
if len(sheets) == 0 {
|
|
return fmt.Errorf("工作簿中没有工作表")
|
|
}
|
|
|
|
rows, err := f.GetRows(sheets[0])
|
|
if err != nil {
|
|
return fmt.Errorf("读取工作表失败: %v", err)
|
|
}
|
|
|
|
if len(rows) < 2 {
|
|
return fmt.Errorf("工作表数据不足")
|
|
}
|
|
|
|
headers := rows[0]
|
|
var jsonData []map[string]string
|
|
|
|
for _, row := range rows[1:] {
|
|
record := make(map[string]string)
|
|
for i, header := range headers {
|
|
if i < len(row) {
|
|
record[header] = row[i]
|
|
} else {
|
|
record[header] = ""
|
|
}
|
|
}
|
|
jsonData = append(jsonData, record)
|
|
}
|
|
|
|
outFile, err := os.Create(outputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("创建输出文件失败: %v", err)
|
|
}
|
|
defer outFile.Close()
|
|
|
|
_, err = outFile.WriteString("[\n")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for i, record := range jsonData {
|
|
_, err = outFile.WriteString(" {\n")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
j := 0
|
|
for key, value := range record {
|
|
_, err = outFile.WriteString(fmt.Sprintf(" \"%s\": \"%s\"", key, value))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if j < len(record)-1 {
|
|
_, err = outFile.WriteString(",\n")
|
|
} else {
|
|
_, err = outFile.WriteString("\n")
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
j++
|
|
}
|
|
|
|
_, err = outFile.WriteString(" }")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if i < len(jsonData)-1 {
|
|
_, err = outFile.WriteString(",\n")
|
|
} else {
|
|
_, err = outFile.WriteString("\n")
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
_, err = outFile.WriteString("]")
|
|
return err
|
|
}
|
|
|
|
func (s *ExcelService) CreateExcelFromData(outputPath string, data [][]string) error {
|
|
f := excelize.NewFile()
|
|
defer f.Close()
|
|
|
|
sheetName := "Sheet1"
|
|
index, err := f.NewSheet(sheetName)
|
|
if err != nil {
|
|
return fmt.Errorf("创建工作表失败: %v", err)
|
|
}
|
|
|
|
f.SetActiveSheet(index)
|
|
|
|
for i, row := range data {
|
|
for j, cell := range row {
|
|
cellName, _ := excelize.CoordinatesToCellName(j+1, i+1)
|
|
f.SetCellValue(sheetName, cellName, cell)
|
|
}
|
|
}
|
|
|
|
if err := f.SaveAs(outputPath); err != nil {
|
|
return fmt.Errorf("保存Excel文件失败: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func containsComma(s string) bool {
|
|
for _, c := range s {
|
|
if c == ',' {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|