тестовый го бэкэнд

This commit is contained in:
Artem Tsyrulnikov
2026-03-27 00:18:42 +03:00
parent 9edb9d6aca
commit 730d453371
7 changed files with 1314 additions and 0 deletions

131
backend/excel_windows.go Normal file
View 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
}