This closes #1057, merge column styles to reduce spreadsheet size

This commit is contained in:
xuri 2021-11-14 00:17:31 +08:00
parent adecf447e1
commit 57275db22e
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
3 changed files with 40 additions and 5 deletions

View File

@ -243,9 +243,9 @@ func TestOutlineLevel(t *testing.T) {
assert.Equal(t, uint8(4), level) assert.Equal(t, uint8(4), level)
assert.NoError(t, err) assert.NoError(t, err)
level, err = f.GetColOutlineLevel("Shee2", "A") level, err = f.GetColOutlineLevel("SheetN", "A")
assert.Equal(t, uint8(0), level) assert.Equal(t, uint8(0), level)
assert.EqualError(t, err, "sheet Shee2 is not exist") assert.EqualError(t, err, "sheet SheetN is not exist")
assert.NoError(t, f.SetColWidth("Sheet2", "A", "D", 13)) assert.NoError(t, f.SetColWidth("Sheet2", "A", "D", 13))
assert.EqualError(t, f.SetColWidth("Sheet2", "A", "D", MaxColumnWidth+1), ErrColumnWidth.Error()) assert.EqualError(t, f.SetColWidth("Sheet2", "A", "D", MaxColumnWidth+1), ErrColumnWidth.Error())

6
lib.go
View File

@ -413,8 +413,8 @@ func defaultTrue(b *bool) bool {
return *b return *b
} }
// MarshalXMLMarshalXML convert the boolean data type to literal values 0 or 1 // MarshalXML convert the boolean data type to literal values 0 or 1 on
// on serialization. // serialization.
func (avb attrValBool) MarshalXML(e *xml.Encoder, start xml.StartElement) error { func (avb attrValBool) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
attr := xml.Attr{ attr := xml.Attr{
Name: xml.Name{ Name: xml.Name{
@ -437,7 +437,7 @@ func (avb attrValBool) MarshalXML(e *xml.Encoder, start xml.StartElement) error
} }
// UnmarshalXML convert the literal values true, false, 1, 0 of the XML // UnmarshalXML convert the literal values true, false, 1, 0 of the XML
// attribute to boolean data type on de-serialization. // attribute to boolean data type on deserialization.
func (avb *attrValBool) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { func (avb *attrValBool) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for { for {
t, err := d.Token() t, err := d.Token()

View File

@ -24,6 +24,7 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"regexp" "regexp"
"sort"
"strconv" "strconv"
"strings" "strings"
"unicode/utf8" "unicode/utf8"
@ -149,6 +150,37 @@ func (f *File) workBookWriter() {
} }
} }
// mergeExpandedCols merge expanded columns.
func (f *File) mergeExpandedCols(ws *xlsxWorksheet) {
sort.Slice(ws.Cols.Col, func(i, j int) bool {
return ws.Cols.Col[i].Min < ws.Cols.Col[j].Min
})
columns := []xlsxCol{}
for i, n := 0, len(ws.Cols.Col); i < n; {
left := i
for i++; i < n && reflect.DeepEqual(
xlsxCol{
BestFit: ws.Cols.Col[i-1].BestFit,
Collapsed: ws.Cols.Col[i-1].Collapsed,
CustomWidth: ws.Cols.Col[i-1].CustomWidth,
Hidden: ws.Cols.Col[i-1].Hidden,
Max: ws.Cols.Col[i-1].Max + 1,
Min: ws.Cols.Col[i-1].Min + 1,
OutlineLevel: ws.Cols.Col[i-1].OutlineLevel,
Phonetic: ws.Cols.Col[i-1].Phonetic,
Style: ws.Cols.Col[i-1].Style,
Width: ws.Cols.Col[i-1].Width,
}, ws.Cols.Col[i]); i++ {
}
column := deepcopy.Copy(ws.Cols.Col[left]).(xlsxCol)
if left < i-1 {
column.Max = ws.Cols.Col[i-1].Min
}
columns = append(columns, column)
}
ws.Cols.Col = columns
}
// workSheetWriter provides a function to save xl/worksheets/sheet%d.xml after // workSheetWriter provides a function to save xl/worksheets/sheet%d.xml after
// serialize structure. // serialize structure.
func (f *File) workSheetWriter() { func (f *File) workSheetWriter() {
@ -161,6 +193,9 @@ func (f *File) workSheetWriter() {
if sheet.MergeCells != nil && len(sheet.MergeCells.Cells) > 0 { if sheet.MergeCells != nil && len(sheet.MergeCells.Cells) > 0 {
_ = f.mergeOverlapCells(sheet) _ = f.mergeOverlapCells(sheet)
} }
if sheet.Cols != nil && len(sheet.Cols.Col) > 0 {
f.mergeExpandedCols(sheet)
}
for k, v := range sheet.SheetData.Row { for k, v := range sheet.SheetData.Row {
sheet.SheetData.Row[k].C = trimCell(v.C) sheet.SheetData.Row[k].C = trimCell(v.C)
} }