- Function `formattedValue()` performance improvement by avoid repeating deserialization, relate issue #64;

- Make function `ToAlphaString()` exportable, relate issue #63
This commit is contained in:
Ri Xu 2017-06-26 18:44:19 +08:00
parent db4aff04fd
commit 35841caaf1
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
6 changed files with 46 additions and 28 deletions

View File

@ -70,8 +70,7 @@ func (f *File) formattedValue(s int, v string) string {
if s == 0 {
return v
}
var styleSheet xlsxStyleSheet
xml.Unmarshal([]byte(f.readXML("xl/styles.xml")), &styleSheet)
styleSheet := f.stylesReader()
ok := builtInNumFmtFunc[styleSheet.CellXfs.Xf[s].NumFmtID]
if ok != nil {
return ok(styleSheet.CellXfs.Xf[s].NumFmtID, v)
@ -200,7 +199,7 @@ func (f *File) MergeCell(sheet, hcell, vcell string) {
if xlsx.MergeCells != nil {
mergeCell := xlsxMergeCell{}
// Correct the coordinate area, such correct C1:B3 to B1:C3.
mergeCell.Ref = toAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1) + ":" + toAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
mergeCell.Ref = ToAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1) + ":" + ToAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
// Delete the merged cells of the overlapping area.
for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
if checkCellInArea(hcell, xlsx.MergeCells.Cells[i].Ref) || checkCellInArea(strings.Split(xlsx.MergeCells.Cells[i].Ref, ":")[0], mergeCell.Ref) {
@ -213,7 +212,7 @@ func (f *File) MergeCell(sheet, hcell, vcell string) {
} else {
mergeCell := xlsxMergeCell{}
// Correct the coordinate area, such correct C1:B3 to B1:C3.
mergeCell.Ref = toAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1) + ":" + toAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
mergeCell.Ref = ToAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1) + ":" + ToAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
mergeCells := xlsxMergeCells{}
mergeCells.Cells = append(mergeCells.Cells, &mergeCell)
xlsx.MergeCells = &mergeCells

View File

@ -20,6 +20,7 @@ type File struct {
Path string
Sheet map[string]*xlsxWorksheet
SheetCount int
Styles *xlsxStyleSheet
WorkBook *xlsxWorkbook
WorkBookRels *xlsxWorkbookRels
XLSX map[string]string
@ -268,7 +269,7 @@ func completeCol(xlsx *xlsxWorksheet, row, cell int) {
if len(v.C) < cell {
start := len(v.C)
for iii := start; iii < cell; iii++ {
buffer.WriteString(toAlphaString(iii + 1))
buffer.WriteString(ToAlphaString(iii + 1))
buffer.WriteString(strconv.Itoa(k + 1))
xlsx.SheetData.Row[k].C = append(xlsx.SheetData.Row[k].C, xlsxC{
R: buffer.String(),
@ -300,7 +301,7 @@ func completeRow(xlsx *xlsxWorksheet, row, cell int) {
start := len(xlsx.SheetData.Row[ii].C)
if start == 0 {
for iii := start; iii < cell; iii++ {
buffer.WriteString(toAlphaString(iii + 1))
buffer.WriteString(ToAlphaString(iii + 1))
buffer.WriteString(strconv.Itoa(ii + 1))
xlsx.SheetData.Row[ii].C = append(xlsx.SheetData.Row[ii].C, xlsxC{
R: buffer.String(),
@ -388,7 +389,7 @@ func checkRow(xlsx *xlsxWorksheet) {
xlsx.SheetData.Row[k].C = xlsx.SheetData.Row[k].C[:0]
tmp := []xlsxC{}
for i := 0; i <= endCol; i++ {
buffer.WriteString(toAlphaString(i + 1))
buffer.WriteString(ToAlphaString(i + 1))
buffer.WriteString(strconv.Itoa(endRow))
tmp = append(tmp, xlsxC{
R: buffer.String(),

View File

@ -57,6 +57,7 @@ func (f *File) Write(w io.Writer) error {
f.workbookWriter()
f.workbookRelsWriter()
f.worksheetWriter()
f.styleSheetWriter()
for path, content := range f.XLSX {
fi, err := zw.Create(path)
if err != nil {

9
lib.go
View File

@ -50,9 +50,12 @@ func readFile(file *zip.File) string {
return string(buff.Bytes())
}
// toAlphaString provides function to convert integer to Excel sheet column
// title.
func toAlphaString(value int) string {
// ToAlphaString provides function to convert integer to Excel sheet column
// title. For example convert 37 to column title AK:
//
// excelize.ToAlphaString(37)
//
func ToAlphaString(value int) string {
if value < 0 {
return ""
}

View File

@ -224,6 +224,26 @@ func parseTime(i int, v string) string {
return val.Format(format)
}
// stylesReader provides function to get the pointer to the structure after
// deserialization of workbook.
func (f *File) stylesReader() *xlsxStyleSheet {
if f.Styles == nil {
var styleSheet xlsxStyleSheet
xml.Unmarshal([]byte(f.readXML("xl/styles.xml")), &styleSheet)
f.Styles = &styleSheet
}
return f.Styles
}
// styleSheetWriter provides function to save xl/styles.xml after serialize
// structure.
func (f *File) styleSheetWriter() {
if f.Styles != nil {
output, _ := xml.Marshal(f.Styles)
f.saveFileList("xl/styles.xml", replaceWorkSheetsRelationshipsNameSpace(string(output)))
}
}
// parseFormatStyleSet provides function to parse the format settings of the
// borders.
func parseFormatStyleSet(style string) (*formatCellStyle, error) {
@ -500,23 +520,17 @@ func parseFormatStyleSet(style string) (*formatCellStyle, error) {
// +-------+----------------------------------------------------+
//
func (f *File) SetCellStyle(sheet, hcell, vcell, style string) error {
var styleSheet xlsxStyleSheet
xml.Unmarshal([]byte(f.readXML("xl/styles.xml")), &styleSheet)
styleSheet := f.stylesReader()
formatCellStyle, err := parseFormatStyleSet(style)
if err != nil {
return err
}
numFmtID := setNumFmt(&styleSheet, formatCellStyle)
fontID := setFont(&styleSheet, formatCellStyle)
borderID := setBorders(&styleSheet, formatCellStyle)
fillID := setFills(&styleSheet, formatCellStyle)
applyAlignment, alignment := setAlignment(&styleSheet, formatCellStyle)
cellXfsID := setCellXfs(&styleSheet, fontID, numFmtID, fillID, borderID, applyAlignment, alignment)
output, err := xml.Marshal(styleSheet)
if err != nil {
return err
}
f.saveFileList("xl/styles.xml", replaceWorkSheetsRelationshipsNameSpace(string(output)))
numFmtID := setNumFmt(styleSheet, formatCellStyle)
fontID := setFont(styleSheet, formatCellStyle)
borderID := setBorders(styleSheet, formatCellStyle)
fillID := setFills(styleSheet, formatCellStyle)
applyAlignment, alignment := setAlignment(styleSheet, formatCellStyle)
cellXfsID := setCellXfs(styleSheet, fontID, numFmtID, fillID, borderID, applyAlignment, alignment)
f.setCellStyle(sheet, hcell, vcell, cellXfsID)
return err
}
@ -771,8 +785,8 @@ func (f *File) setCellStyle(sheet, hcell, vcell string, styleID int) {
}
// Correct the coordinate area, such correct C1:B3 to B1:C3.
hcell = toAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1)
vcell = toAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
hcell = ToAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1)
vcell = ToAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
xlsx := f.workSheetReader(sheet)

View File

@ -108,12 +108,12 @@ func (f *File) addTable(sheet, tableXML string, hxAxis, hyAxis, vxAxis, vyAxis,
vyAxis++
}
// Correct table reference coordinate area, such correct C1:B3 to B1:C3.
ref := toAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1) + ":" + toAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
ref := ToAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1) + ":" + ToAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
tableColumn := []*xlsxTableColumn{}
idx := 0
for i := hxAxis; i <= vxAxis; i++ {
idx++
cell := toAlphaString(i+1) + strconv.Itoa(hyAxis+1)
cell := ToAlphaString(i+1) + strconv.Itoa(hyAxis+1)
name := f.GetCellValue(sheet, cell)
if _, err := strconv.Atoi(name); err == nil {
f.SetCellStr(sheet, cell, name)
@ -254,7 +254,7 @@ func (f *File) AutoFilter(sheet, hcell, vcell, format string) error {
if vyAxis < hyAxis {
vyAxis, hyAxis = hyAxis, vyAxis
}
ref := toAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1) + ":" + toAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
ref := ToAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1) + ":" + ToAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
refRange := vxAxis - hxAxis
err := f.autoFilter(sheet, ref, refRange, hxAxis, formatSet)
return err