forked from p30928647/excelize
- Function `formattedValue()` performance improvement by avoid repeating deserialization, relate issue #64;
- Make function `ToAlphaString()` exportable, relate issue #63
This commit is contained in:
parent
db4aff04fd
commit
35841caaf1
7
cell.go
7
cell.go
|
@ -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(),
|
||||||
|
|
1
file.go
1
file.go
|
@ -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 {
|
||||||
|
|
9
lib.go
9
lib.go
|
@ -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 ""
|
||||||
}
|
}
|
||||||
|
|
44
styles.go
44
styles.go
|
@ -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)
|
||||||
|
|
||||||
|
|
6
table.go
6
table.go
|
@ -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…
Reference in New Issue