Files
file-tool-wails/services/excel_service.go
2026-06-17 08:05:20 +08:00

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
}