Vyacheslav Zgordan a5ef37c0bc
Spreadsheet formulas: Flattening files (#366)
* evaluation errors fixed
* allow underscores in sheet names
* allow wildcard in *LOOKUP functions
* horizontal and vertical ranges
* horizontal and vertical ranges for sheet references
* remove redundant recalculate
* caching
* fixed named ranges, made Evaluator more generic
* Memory usage shown in flatten example
* temporary file deleted
* ParseCellReference duplicate removed
* ISREF is fixed
2020-01-29 10:43:43 +00:00

80 lines
1.9 KiB
Go

// Copyright 2017 FoxyUtils ehf. All rights reserved.
package main
// This example demonstrates flattening all formulas from an input Excel file and outputs the flattened values to a new xlsx.
import (
"log"
"fmt"
"runtime"
"time"
"github.com/unidoc/unioffice/spreadsheet"
"github.com/unidoc/unioffice/spreadsheet/formula"
)
func main() {
ss, err := spreadsheet.Open("formulas.xlsx")
if err != nil {
log.Fatalf("error opening document: %s", err)
}
sheets := ss.Sheets()
start := time.Now().UnixNano()
formEv := formula.NewEvaluator()
for _, sheet := range sheets {
fmt.Println("Sheet name:", sheet.Name())
ctx := sheet.FormulaContext()
for _, row := range sheet.Rows() {
for _, cell := range row.Cells() {
c := ctx.Cell(cell.Reference(), formEv)
value := ""
if cell.X().V != nil {
value = *cell.X().V
}
cell.Clear()
setValue(cell, c, value)
}
}
}
finish := time.Now().UnixNano()
fmt.Printf("total time: %d ns\n", finish - start)
PrintMemUsage()
ss.SaveToFile("values.xlsx")
}
func setValue(cell spreadsheet.Cell, c formula.Result, value string) {
switch c.Type {
case formula.ResultTypeNumber:
if c.IsBoolean {
cell.SetBool(value != "0")
} else {
cell.SetNumber(c.ValueNumber)
}
case formula.ResultTypeString:
cell.SetString(c.ValueString)
case formula.ResultTypeList:
setValue(cell, c.ValueList[0], value)
case formula.ResultTypeArray:
setValue(cell, c.ValueArray[0][0], value)
case formula.ResultTypeError:
cell.SetError(c.ValueString)
}
}
func PrintMemUsage() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
fmt.Println("Memory usage:")
fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
fmt.Printf("\tNumGC = %v\n", m.NumGC)
}
func bToMb(b uint64) uint64 {
return b / 1024 / 1024
}