mirror of
https://github.com/unidoc/unioffice.git
synced 2025-04-27 13:48:54 +08:00
spreadsheet: merge spreadsheet/style package into spreadsheet
This commit is contained in:
parent
3e1bcdd646
commit
d186678dbb
Binary file not shown.
30
_examples/spreadsheet/wrapped-text/main.go
Normal file
30
_examples/spreadsheet/wrapped-text/main.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2017 Baliance. All rights reserved.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"baliance.com/gooxml/spreadsheet"
|
||||||
|
)
|
||||||
|
|
||||||
|
var lorem = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin lobortis, lectus dictum feugiat tempus, sem neque finibus enim, sed eleifend sem nunc ac diam. Vestibulum tempus sagittis elementum`
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ss := spreadsheet.New()
|
||||||
|
// add a single sheet
|
||||||
|
sheet := ss.AddSheet()
|
||||||
|
|
||||||
|
row := sheet.AddRow()
|
||||||
|
cell := row.AddCell()
|
||||||
|
|
||||||
|
wrapped := ss.StyleSheet.AddCellStyle()
|
||||||
|
wrapped.SetWrapped(true)
|
||||||
|
cell.SetString(lorem)
|
||||||
|
cell.SetStyle(wrapped)
|
||||||
|
|
||||||
|
if err := ss.Validate(); err != nil {
|
||||||
|
log.Fatalf("error validating sheet: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ss.SaveToFile("wrapped.xlsx")
|
||||||
|
}
|
BIN
_examples/spreadsheet/wrapped-text/wrapped.xlsx
Normal file
BIN
_examples/spreadsheet/wrapped-text/wrapped.xlsx
Normal file
Binary file not shown.
@ -5,7 +5,7 @@
|
|||||||
// appearing in the file LICENSE included in the packaging of this file. A
|
// appearing in the file LICENSE included in the packaging of this file. A
|
||||||
// commercial license can be purchased by contacting sales@baliance.com.
|
// commercial license can be purchased by contacting sales@baliance.com.
|
||||||
|
|
||||||
package styles
|
package spreadsheet
|
||||||
|
|
||||||
import sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
import sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
||||||
|
|
@ -12,7 +12,6 @@ import (
|
|||||||
|
|
||||||
"baliance.com/gooxml"
|
"baliance.com/gooxml"
|
||||||
sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
||||||
"baliance.com/gooxml/spreadsheet/styles"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Cell is a single cell within a sheet.
|
// Cell is a single cell within a sheet.
|
||||||
@ -73,7 +72,7 @@ func (c Cell) SetBool(v bool) {
|
|||||||
|
|
||||||
// SetStyle applies a style to the cell. This style is referenced in the generated XML
|
// SetStyle applies a style to the cell. This style is referenced in the generated XML
|
||||||
// via CellStyle.Index().
|
// via CellStyle.Index().
|
||||||
func (c Cell) SetStyle(cs styles.CellStyle) {
|
func (c Cell) SetStyle(cs CellStyle) {
|
||||||
c.x.SAttr = gooxml.Uint32(cs.Index())
|
c.x.SAttr = gooxml.Uint32(cs.Index())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
|||||||
|
|
||||||
func TestCell(t *testing.T) {
|
func TestCell(t *testing.T) {
|
||||||
wb := spreadsheet.New()
|
wb := spreadsheet.New()
|
||||||
sheet := wb.AddSheet("test")
|
sheet := wb.AddSheet()
|
||||||
row := sheet.AddRow()
|
row := sheet.AddRow()
|
||||||
cell := row.AddCell()
|
cell := row.AddCell()
|
||||||
|
|
||||||
|
@ -5,20 +5,42 @@
|
|||||||
// appearing in the file LICENSE included in the packaging of this file. A
|
// appearing in the file LICENSE included in the packaging of this file. A
|
||||||
// commercial license can be purchased by contacting sales@baliance.com.
|
// commercial license can be purchased by contacting sales@baliance.com.
|
||||||
|
|
||||||
package styles
|
package spreadsheet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baliance.com/gooxml"
|
"baliance.com/gooxml"
|
||||||
sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// CellStyle is a formatting style for a cell. CellStyles are spreadsheet global
|
||||||
|
// and can be applied to cells across sheets.
|
||||||
type CellStyle struct {
|
type CellStyle struct {
|
||||||
xf *sml.CT_Xf
|
xf *sml.CT_Xf
|
||||||
xfs *sml.CT_CellXfs
|
xfs *sml.CT_CellXfs
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCellStyle(xf *sml.CT_Xf, xfs *sml.CT_CellXfs) CellStyle {
|
// Wrapped returns true if the cell will wrap text.
|
||||||
return CellStyle{xf, xfs}
|
func (cs CellStyle) Wrapped() bool {
|
||||||
|
if cs.xf.Alignment == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if cs.xf.Alignment.WrapTextAttr == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return *cs.xf.Alignment.WrapTextAttr
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWrapped configures the cell to wrap text.
|
||||||
|
func (cs CellStyle) SetWrapped(b bool) {
|
||||||
|
if cs.xf.Alignment == nil {
|
||||||
|
cs.xf.Alignment = sml.NewCT_CellAlignment()
|
||||||
|
}
|
||||||
|
if !b {
|
||||||
|
cs.xf.Alignment.WrapTextAttr = nil
|
||||||
|
} else {
|
||||||
|
cs.xf.Alignment.WrapTextAttr = gooxml.Bool(true)
|
||||||
|
cs.xf.ApplyAlignmentAttr = gooxml.Bool(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHorizontalAlignment sets the horizontal alignment of a cell style.
|
// SetHorizontalAlignment sets the horizontal alignment of a cell style.
|
||||||
@ -26,8 +48,8 @@ func (cs CellStyle) SetHorizontalAlignment(a sml.ST_HorizontalAlignment) {
|
|||||||
if cs.xf.Alignment == nil {
|
if cs.xf.Alignment == nil {
|
||||||
cs.xf.Alignment = sml.NewCT_CellAlignment()
|
cs.xf.Alignment = sml.NewCT_CellAlignment()
|
||||||
}
|
}
|
||||||
cs.xf.ApplyAlignmentAttr = gooxml.Bool(true)
|
|
||||||
cs.xf.Alignment.HorizontalAttr = a
|
cs.xf.Alignment.HorizontalAttr = a
|
||||||
|
cs.xf.ApplyAlignmentAttr = gooxml.Bool(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVerticalAlignment sets the vertical alignment of a cell style.
|
// SetVerticalAlignment sets the vertical alignment of a cell style.
|
@ -5,7 +5,7 @@
|
|||||||
// appearing in the file LICENSE included in the packaging of this file. A
|
// appearing in the file LICENSE included in the packaging of this file. A
|
||||||
// commercial license can be purchased by contacting sales@baliance.com.
|
// commercial license can be purchased by contacting sales@baliance.com.
|
||||||
|
|
||||||
package styles
|
package spreadsheet
|
||||||
|
|
||||||
import sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
import sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
||||||
|
|
@ -5,25 +5,24 @@
|
|||||||
// appearing in the file LICENSE included in the packaging of this file. A
|
// appearing in the file LICENSE included in the packaging of this file. A
|
||||||
// commercial license can be purchased by contacting sales@baliance.com.
|
// commercial license can be purchased by contacting sales@baliance.com.
|
||||||
|
|
||||||
package styles
|
package spreadsheet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baliance.com/gooxml/color"
|
"baliance.com/gooxml/color"
|
||||||
sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
sml "baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Font allows editing fonts within a spreadsheet stylesheet.
|
||||||
type Font struct {
|
type Font struct {
|
||||||
font *sml.CT_Font
|
font *sml.CT_Font
|
||||||
styles *sml.StyleSheet
|
styles *sml.StyleSheet
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFont(font *sml.CT_Font, styles *sml.StyleSheet) Font {
|
// X returns the inner wrapped XML type.
|
||||||
return Font{font, styles}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Font) X() *sml.CT_Font {
|
func (f Font) X() *sml.CT_Font {
|
||||||
return f.font
|
return f.font
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Font) Index() uint32 {
|
func (f Font) Index() uint32 {
|
||||||
for i, sf := range f.styles.Fonts.Font {
|
for i, sf := range f.styles.Fonts.Font {
|
||||||
if f.font == sf {
|
if f.font == sf {
|
@ -5,7 +5,7 @@
|
|||||||
// appearing in the file LICENSE included in the packaging of this file. A
|
// appearing in the file LICENSE included in the packaging of this file. A
|
||||||
// commercial license can be purchased by contacting sales@baliance.com.
|
// commercial license can be purchased by contacting sales@baliance.com.
|
||||||
|
|
||||||
package styles
|
package spreadsheet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"baliance.com/gooxml/color"
|
"baliance.com/gooxml/color"
|
@ -5,7 +5,7 @@
|
|||||||
// appearing in the file LICENSE included in the packaging of this file. A
|
// appearing in the file LICENSE included in the packaging of this file. A
|
||||||
// commercial license can be purchased by contacting sales@baliance.com.
|
// commercial license can be purchased by contacting sales@baliance.com.
|
||||||
|
|
||||||
package styles
|
package spreadsheet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@ -76,7 +76,7 @@ func (s StyleSheet) AddFont() Font {
|
|||||||
font := sml.NewCT_Font()
|
font := sml.NewCT_Font()
|
||||||
s.x.Fonts.Font = append(s.x.Fonts.Font, font)
|
s.x.Fonts.Font = append(s.x.Fonts.Font, font)
|
||||||
s.x.Fonts.CountAttr = gooxml.Uint32(uint32(len(s.x.Fonts.Font)))
|
s.x.Fonts.CountAttr = gooxml.Uint32(uint32(len(s.x.Fonts.Font)))
|
||||||
return NewFont(font, s.x)
|
return Font{font, s.x}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveFont removes a font from the style sheet. It *does not* update styles that refer
|
// RemoveFont removes a font from the style sheet. It *does not* update styles that refer
|
||||||
@ -96,7 +96,7 @@ func (s StyleSheet) RemoveFont(f Font) error {
|
|||||||
func (s StyleSheet) Fonts() []Font {
|
func (s StyleSheet) Fonts() []Font {
|
||||||
ret := []Font{}
|
ret := []Font{}
|
||||||
for _, f := range s.x.Fonts.Font {
|
for _, f := range s.x.Fonts.Font {
|
||||||
ret = append(ret, NewFont(f, s.x))
|
ret = append(ret, Font{f, s.x})
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ func (s StyleSheet) AddCellStyle() CellStyle {
|
|||||||
xf := sml.NewCT_Xf()
|
xf := sml.NewCT_Xf()
|
||||||
s.x.CellXfs.Xf = append(s.x.CellXfs.Xf, xf)
|
s.x.CellXfs.Xf = append(s.x.CellXfs.Xf, xf)
|
||||||
s.x.CellXfs.CountAttr = gooxml.Uint32(uint32(len(s.x.CellXfs.Xf)))
|
s.x.CellXfs.CountAttr = gooxml.Uint32(uint32(len(s.x.CellXfs.Xf)))
|
||||||
return NewCellStyle(xf, s.x.CellXfs)
|
return CellStyle{xf, s.x.CellXfs}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fills returns a Fills object that can be used to add/create/edit fills.
|
// Fills returns a Fills object that can be used to add/create/edit fills.
|
@ -5,7 +5,7 @@
|
|||||||
// appearing in the file LICENSE included in the packaging of this file. A
|
// appearing in the file LICENSE included in the packaging of this file. A
|
||||||
// commercial license can be purchased by contacting sales@baliance.com.
|
// commercial license can be purchased by contacting sales@baliance.com.
|
||||||
|
|
||||||
package styles_test
|
package spreadsheet_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -14,7 +14,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"baliance.com/gooxml/spreadsheet/styles"
|
"baliance.com/gooxml/spreadsheet"
|
||||||
"baliance.com/gooxml/testhelper"
|
"baliance.com/gooxml/testhelper"
|
||||||
"baliance.com/gooxml/zippkg"
|
"baliance.com/gooxml/zippkg"
|
||||||
)
|
)
|
||||||
@ -22,25 +22,25 @@ import (
|
|||||||
func TestStyleSheetUnmarshal(t *testing.T) {
|
func TestStyleSheetUnmarshal(t *testing.T) {
|
||||||
f, err := os.Open("testdata/styles.xml")
|
f, err := os.Open("testdata/styles.xml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error reading content types file")
|
t.Fatalf("error reading styles.xml")
|
||||||
}
|
}
|
||||||
dec := xml.NewDecoder(f)
|
dec := xml.NewDecoder(f)
|
||||||
r := styles.NewStyleSheet()
|
r := spreadsheet.NewStyleSheet()
|
||||||
if err := dec.Decode(r.X()); err != nil {
|
if err := dec.Decode(r.X()); err != nil {
|
||||||
t.Errorf("error decoding content types: %s", err)
|
t.Errorf("error decoding styles.xml: %s", err)
|
||||||
}
|
}
|
||||||
got := &bytes.Buffer{}
|
got := &bytes.Buffer{}
|
||||||
fmt.Fprintf(got, zippkg.XMLHeader)
|
fmt.Fprintf(got, zippkg.XMLHeader)
|
||||||
enc := xml.NewEncoder(zippkg.SelfClosingWriter{W: got})
|
enc := xml.NewEncoder(zippkg.SelfClosingWriter{W: got})
|
||||||
if err := enc.Encode(r.X()); err != nil {
|
if err := enc.Encode(r.X()); err != nil {
|
||||||
t.Errorf("error encoding content types: %s", err)
|
t.Errorf("error encoding styles.xml: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
testhelper.CompareGoldenXML(t, "styles.xml", got.Bytes())
|
testhelper.CompareGoldenXML(t, "styles.xml", got.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStyleSheetFonts(t *testing.T) {
|
func TestStyleSheetFonts(t *testing.T) {
|
||||||
ss := styles.NewStyleSheet()
|
ss := spreadsheet.NewStyleSheet()
|
||||||
fc := len(ss.Fonts())
|
fc := len(ss.Fonts())
|
||||||
ft := ss.AddFont()
|
ft := ss.AddFont()
|
||||||
|
|
@ -19,7 +19,6 @@ import (
|
|||||||
|
|
||||||
"baliance.com/gooxml/common"
|
"baliance.com/gooxml/common"
|
||||||
"baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
"baliance.com/gooxml/schema/schemas.openxmlformats.org/spreadsheetml"
|
||||||
"baliance.com/gooxml/spreadsheet/styles"
|
|
||||||
"baliance.com/gooxml/zippkg"
|
"baliance.com/gooxml/zippkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,7 +27,7 @@ type Workbook struct {
|
|||||||
common.DocBase
|
common.DocBase
|
||||||
x *spreadsheetml.Workbook
|
x *spreadsheetml.Workbook
|
||||||
|
|
||||||
StyleSheet styles.StyleSheet
|
StyleSheet StyleSheet
|
||||||
Theme common.Theme
|
Theme common.Theme
|
||||||
SharedStrings SharedStrings
|
SharedStrings SharedStrings
|
||||||
xws []*spreadsheetml.Worksheet
|
xws []*spreadsheetml.Worksheet
|
||||||
@ -43,7 +42,7 @@ func New() *Workbook {
|
|||||||
|
|
||||||
wb.AppProperties = common.NewAppProperties()
|
wb.AppProperties = common.NewAppProperties()
|
||||||
wb.CoreProperties = common.NewCoreProperties()
|
wb.CoreProperties = common.NewCoreProperties()
|
||||||
wb.StyleSheet = styles.NewStyleSheet()
|
wb.StyleSheet = NewStyleSheet()
|
||||||
|
|
||||||
wb.Rels = common.NewRelationships()
|
wb.Rels = common.NewRelationships()
|
||||||
wb.wbRels = common.NewRelationships()
|
wb.wbRels = common.NewRelationships()
|
||||||
@ -148,7 +147,7 @@ func Read(r io.ReaderAt, size int64) (*Workbook, error) {
|
|||||||
basePaths[wksRel] = basePath
|
basePaths[wksRel] = basePath
|
||||||
wb.xwsRels = append(wb.xwsRels, wksRel)
|
wb.xwsRels = append(wb.xwsRels, wksRel)
|
||||||
case common.StylesType:
|
case common.StylesType:
|
||||||
wb.StyleSheet = styles.NewStyleSheet()
|
wb.StyleSheet = NewStyleSheet()
|
||||||
decMap[basePaths[wb.wbRels]+r.Target()] = wb.StyleSheet.X()
|
decMap[basePaths[wb.wbRels]+r.Target()] = wb.StyleSheet.X()
|
||||||
case common.ThemeType:
|
case common.ThemeType:
|
||||||
wb.Theme = common.NewTheme()
|
wb.Theme = common.NewTheme()
|
||||||
|
@ -67,7 +67,7 @@ func TestWorkbookUnmarshal(t *testing.T) {
|
|||||||
|
|
||||||
func TestSimpleSheet(t *testing.T) {
|
func TestSimpleSheet(t *testing.T) {
|
||||||
wb := spreadsheet.New()
|
wb := spreadsheet.New()
|
||||||
sheet := wb.AddSheet("foo")
|
sheet := wb.AddSheet()
|
||||||
row := sheet.AddRow()
|
row := sheet.AddRow()
|
||||||
cell := row.AddCell()
|
cell := row.AddCell()
|
||||||
cell.SetString("testing 123")
|
cell.SetString("testing 123")
|
||||||
@ -114,14 +114,14 @@ func TestSheetCount(t *testing.T) {
|
|||||||
if wb.SheetCount() != 0 {
|
if wb.SheetCount() != 0 {
|
||||||
t.Errorf("expected 0 sheets, got %d", wb.SheetCount())
|
t.Errorf("expected 0 sheets, got %d", wb.SheetCount())
|
||||||
}
|
}
|
||||||
wb.AddSheet("Sheet 1")
|
wb.AddSheet()
|
||||||
if err := wb.Validate(); err != nil {
|
if err := wb.Validate(); err != nil {
|
||||||
t.Errorf("created an invalid spreadsheet: %s", err)
|
t.Errorf("created an invalid spreadsheet: %s", err)
|
||||||
}
|
}
|
||||||
if wb.SheetCount() != 1 {
|
if wb.SheetCount() != 1 {
|
||||||
t.Errorf("expected 1 sheets, got %d", wb.SheetCount())
|
t.Errorf("expected 1 sheets, got %d", wb.SheetCount())
|
||||||
}
|
}
|
||||||
wb.AddSheet("Sheet 2")
|
wb.AddSheet()
|
||||||
if err := wb.Validate(); err != nil {
|
if err := wb.Validate(); err != nil {
|
||||||
t.Errorf("created an invalid spreadsheet: %s", err)
|
t.Errorf("created an invalid spreadsheet: %s", err)
|
||||||
}
|
}
|
||||||
@ -132,7 +132,7 @@ func TestSheetCount(t *testing.T) {
|
|||||||
|
|
||||||
func TestPreserveSpace(t *testing.T) {
|
func TestPreserveSpace(t *testing.T) {
|
||||||
ss := spreadsheet.New()
|
ss := spreadsheet.New()
|
||||||
sheet := ss.AddSheet("Sheet 1")
|
sheet := ss.AddSheet()
|
||||||
row := sheet.AddRow()
|
row := sheet.AddRow()
|
||||||
values := []string{" foo ", " bar \t", "foo\r\nbar", "\t\r\nfoo\t123\r\n"}
|
values := []string{" foo ", " bar \t", "foo\r\nbar", "\t\r\nfoo\t123\r\n"}
|
||||||
for i, s := range values {
|
for i, s := range values {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user