132 lines
4.0 KiB
Go
132 lines
4.0 KiB
Go
//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
|
|
}
|