spreadsheet: add formula reading/writing support

Minimal support for now, just enough to read table
ranges so they can be used from formulas.
This commit is contained in:
Todd 2017-09-17 12:58:51 -05:00
parent 5ed34695bd
commit a4a1562f7c
5 changed files with 65 additions and 0 deletions

View File

@ -53,6 +53,9 @@ func RelativeFilename(dt DocType, typ string, index int) string {
case VMLDrawingType, VMLDrawingContentType:
return fmt.Sprintf("../drawings/vmlDrawing%d.vml", index)
case TableType, TableContentType:
return fmt.Sprintf("../tables/table%d.xml", index)
case ThemeType, ThemeContentType:
return fmt.Sprintf("theme/theme%d.xml", index)
case OfficeDocumentType:
@ -144,6 +147,8 @@ func AbsoluteFilename(dt DocType, typ string, index int) string {
default:
log.Printf("unsupported type %s pair and %v", typ, dt)
}
case TableType, TableContentType:
return fmt.Sprintf("xl/tables/table%d.xml", index)
case DrawingType, DrawingContentType:
switch dt {

View File

@ -33,6 +33,8 @@ const (
SharedStingsType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"
SharedStringsContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"
SMLStyleSheetContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"
TableType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"
TableContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"
// WML
HeaderType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"

View File

@ -598,6 +598,8 @@ func (s *Sheet) SetFrozen(firstRow, firstCol bool) {
}
// FormulaContext returns a formula evaluation context that can be used to
// evaluate formaulas.
func (s *Sheet) FormulaContext() formula.Context {
return newEvalContext(s)
}

32
spreadsheet/table.go Normal file
View File

@ -0,0 +1,32 @@
// Copyright 2017 Baliance. All rights reserved.
//
// Use of this source code is governed by the terms of the Affero GNU General
// Public License version 3.0 as published by the Free Software Foundation and
// appearing in the file LICENSE included in the packaging of this file. A
// commercial license can be purchased by contacting sales@baliance.com.
package spreadsheet
import sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
type Table struct {
x *sml.Table
}
// X returns the inner wrapped XML type.
func (t Table) X() *sml.Table {
return t.x
}
// Name returns the name of the table
func (t Table) Name() string {
if t.x.NameAttr != nil {
return *t.x.NameAttr
}
return ""
}
// Reference returns the table reference (the cells within the table)
func (t Table) Reference() string {
return t.x.RefAttr
}

View File

@ -47,6 +47,7 @@ type Workbook struct {
drawingRels []common.Relationships
vmlDrawings []*vmldrawing.Container
charts []*crt.ChartSpace
tables []*sml.Table
}
// X returns the inner wrapped XML type.
@ -176,6 +177,10 @@ func (wb *Workbook) Save(w io.Writer) error {
fn := gooxml.AbsoluteFilename(dt, gooxml.ChartType, i+1)
zippkg.MarshalXML(z, fn, chart)
}
for i, tbl := range wb.tables {
fn := gooxml.AbsoluteFilename(dt, gooxml.TableType, i+1)
zippkg.MarshalXML(z, fn, tbl)
}
for i, drawing := range wb.drawings {
fn := gooxml.AbsoluteFilename(dt, gooxml.DrawingType, i+1)
zippkg.MarshalXML(z, fn, drawing)
@ -389,6 +394,13 @@ func (wb *Workbook) onNewRelationship(decMap *zippkg.DecodeMap, target, typ stri
wb.charts = append(wb.charts, chart)
rel.TargetAttr = gooxml.RelativeFilename(dt, typ, len(wb.charts))
case gooxml.TableType:
tbl := sml.NewTable()
idx := uint32(len(wb.tables))
decMap.AddTarget(zippkg.Target{Path: target, Ifc: tbl, Index: idx})
wb.tables = append(wb.tables, tbl)
rel.TargetAttr = gooxml.RelativeFilename(dt, typ, len(wb.charts))
default:
log.Printf("unsupported relationship %s %s", target, typ)
}
@ -500,3 +512,15 @@ func (wb *Workbook) SetActiveSheetIndex(idx uint32) {
wb.x.BookViews.WorkbookView[0].ActiveTabAttr = gooxml.Uint32(idx)
}
// Tables returns a slice of all defined tables in the workbook.
func (w *Workbook) Tables() []Table {
if w.tables == nil {
return nil
}
ret := []Table{}
for _, t := range w.tables {
ret = append(ret, Table{t})
}
return ret
}