тестовый го бэкэнд
This commit is contained in:
131
backend/excel_windows.go
Normal file
131
backend/excel_windows.go
Normal file
@@ -0,0 +1,131 @@
|
||||
//go:build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/go-ole/go-ole/oleutil"
|
||||
)
|
||||
|
||||
func FillCells(cells map[string]interface{}, fileContent []byte, printArea string) ([]byte, error) {
|
||||
ole.CoInitialize(0)
|
||||
defer ole.CoUninitialize()
|
||||
|
||||
tmpInput, err := os.CreateTemp("", "*.xlsx")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tmpInput.Write(fileContent)
|
||||
tmpInput.Close()
|
||||
inputPath, _ := filepath.Abs(tmpInput.Name())
|
||||
defer os.Remove(inputPath)
|
||||
|
||||
outputPath, _ := filepath.Abs(filepath.Join(os.TempDir(), "out_"+filepath.Base(inputPath)))
|
||||
defer os.Remove(outputPath)
|
||||
|
||||
unknown, err := oleutil.CreateObject("Excel.Application")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Excel COM not available: %w", err)
|
||||
}
|
||||
excel, _ := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
defer excel.Release()
|
||||
|
||||
oleutil.PutProperty(excel, "Visible", false)
|
||||
oleutil.PutProperty(excel, "DisplayAlerts", false)
|
||||
|
||||
workbooks := oleutil.MustGetProperty(excel, "Workbooks").ToIDispatch()
|
||||
workbook := oleutil.MustCallMethod(workbooks, "Open", inputPath).ToIDispatch()
|
||||
sheet := oleutil.MustGetProperty(workbook, "ActiveSheet").ToIDispatch()
|
||||
|
||||
for addr, value := range cells {
|
||||
cell := oleutil.MustGetProperty(sheet, "Range", addr).ToIDispatch()
|
||||
oleutil.PutProperty(cell, "Value", value)
|
||||
cell.Release()
|
||||
}
|
||||
|
||||
if printArea != "" {
|
||||
pageSetup := oleutil.MustGetProperty(sheet, "PageSetup").ToIDispatch()
|
||||
oleutil.PutProperty(pageSetup, "PrintArea", printArea)
|
||||
pageSetup.Release()
|
||||
}
|
||||
|
||||
oleutil.MustCallMethod(workbook, "SaveAs", outputPath)
|
||||
oleutil.MustCallMethod(workbook, "Close")
|
||||
oleutil.MustCallMethod(excel, "Quit")
|
||||
|
||||
return os.ReadFile(outputPath)
|
||||
}
|
||||
|
||||
func ReadCells(fileContent []byte) (map[string]interface{}, error) {
|
||||
ole.CoInitialize(0)
|
||||
defer ole.CoUninitialize()
|
||||
|
||||
tmpInput, err := os.CreateTemp("", "*.xlsx")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tmpInput.Write(fileContent)
|
||||
tmpInput.Close()
|
||||
inputPath, _ := filepath.Abs(tmpInput.Name())
|
||||
defer os.Remove(inputPath)
|
||||
|
||||
unknown, err := oleutil.CreateObject("Excel.Application")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Excel COM not available: %w", err)
|
||||
}
|
||||
excel, _ := unknown.QueryInterface(ole.IID_IDispatch)
|
||||
defer excel.Release()
|
||||
|
||||
oleutil.PutProperty(excel, "Visible", false)
|
||||
oleutil.PutProperty(excel, "DisplayAlerts", false)
|
||||
|
||||
workbooks := oleutil.MustGetProperty(excel, "Workbooks").ToIDispatch()
|
||||
workbook := oleutil.MustCallMethod(workbooks, "Open", inputPath).ToIDispatch()
|
||||
sheet := oleutil.MustGetProperty(workbook, "ActiveSheet").ToIDispatch()
|
||||
|
||||
usedRange := oleutil.MustGetProperty(sheet, "UsedRange").ToIDispatch()
|
||||
rowCount := int(oleutil.MustGetProperty(oleutil.MustGetProperty(usedRange, "Rows").ToIDispatch(), "Count").Val)
|
||||
colCount := int(oleutil.MustGetProperty(oleutil.MustGetProperty(usedRange, "Columns").ToIDispatch(), "Count").Val)
|
||||
|
||||
cells := map[string]interface{}{}
|
||||
for r := 1; r <= rowCount; r++ {
|
||||
for c := 1; c <= colCount; c++ {
|
||||
cell := oleutil.MustGetProperty(sheet, "Cells", r, c).ToIDispatch()
|
||||
val, _ := oleutil.GetProperty(cell, "Value")
|
||||
if val.Val != 0 {
|
||||
addr := oleutil.MustGetProperty(cell, "Address", false, false).ToString()
|
||||
addr = strings.ReplaceAll(addr, "$", "")
|
||||
cells[addr] = val.Value()
|
||||
}
|
||||
cell.Release()
|
||||
}
|
||||
}
|
||||
|
||||
var merged []map[string]string
|
||||
mergedAreas := oleutil.MustGetProperty(sheet, "MergedCells").ToIDispatch()
|
||||
if mergedAreas != nil {
|
||||
mergeCount, err := oleutil.GetProperty(mergedAreas, "Count")
|
||||
if err == nil && mergeCount.Val > 0 {
|
||||
for i := 1; i <= int(mergeCount.Val); i++ {
|
||||
area := oleutil.MustGetProperty(mergedAreas, "Item", i).ToIDispatch()
|
||||
addrStr := oleutil.MustGetProperty(area, "Address", false, false).ToString()
|
||||
addrStr = strings.ReplaceAll(addrStr, "$", "")
|
||||
parts := strings.Split(addrStr, ":")
|
||||
if len(parts) == 2 {
|
||||
merged = append(merged, map[string]string{"from": parts[0], "to": parts[1]})
|
||||
}
|
||||
area.Release()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oleutil.MustCallMethod(workbook, "Close", false)
|
||||
oleutil.MustCallMethod(excel, "Quit")
|
||||
|
||||
return map[string]interface{}{"cells": cells, "merged": merged}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user