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

- Make function `ToAlphaString()` exportable, relate issue #63
formula
Ri Xu 8 years ago
parent db4aff04fd
commit 35841caaf1
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7

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

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

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

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

@ -224,6 +224,26 @@ func parseTime(i int, v string) string {
return val.Format(format) 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 // parseFormatStyleSet provides function to parse the format settings of the
// borders. // borders.
func parseFormatStyleSet(style string) (*formatCellStyle, error) { 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 { func (f *File) SetCellStyle(sheet, hcell, vcell, style string) error {
var styleSheet xlsxStyleSheet styleSheet := f.stylesReader()
xml.Unmarshal([]byte(f.readXML("xl/styles.xml")), &styleSheet)
formatCellStyle, err := parseFormatStyleSet(style) formatCellStyle, err := parseFormatStyleSet(style)
if err != nil { if err != nil {
return err return err
} }
numFmtID := setNumFmt(&styleSheet, formatCellStyle) numFmtID := setNumFmt(styleSheet, formatCellStyle)
fontID := setFont(&styleSheet, formatCellStyle) fontID := setFont(styleSheet, formatCellStyle)
borderID := setBorders(&styleSheet, formatCellStyle) borderID := setBorders(styleSheet, formatCellStyle)
fillID := setFills(&styleSheet, formatCellStyle) fillID := setFills(styleSheet, formatCellStyle)
applyAlignment, alignment := setAlignment(&styleSheet, formatCellStyle) applyAlignment, alignment := setAlignment(styleSheet, formatCellStyle)
cellXfsID := setCellXfs(&styleSheet, fontID, numFmtID, fillID, borderID, applyAlignment, alignment) 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)))
f.setCellStyle(sheet, hcell, vcell, cellXfsID) f.setCellStyle(sheet, hcell, vcell, cellXfsID)
return err 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. // Correct the coordinate area, such correct C1:B3 to B1:C3.
hcell = toAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1) hcell = ToAlphaString(hxAxis+1) + strconv.Itoa(hyAxis+1)
vcell = toAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1) vcell = ToAlphaString(vxAxis+1) + strconv.Itoa(vyAxis+1)
xlsx := f.workSheetReader(sheet) xlsx := f.workSheetReader(sheet)

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

Loading…
Cancel
Save