From 330c7a0925353c8458747b309ad94067beae1d34 Mon Sep 17 00:00:00 2001 From: Ri Xu Date: Fri, 31 Mar 2017 17:14:35 +0800 Subject: [PATCH] Performance enhancements, remove redundant XML element checking logic. Relate issue #29. The benchmark report of the current version of this library is shown on the wiki page. --- excelize.go | 56 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/excelize.go b/excelize.go index e723cb5..e53d9f0 100644 --- a/excelize.go +++ b/excelize.go @@ -100,6 +100,7 @@ func (f *File) workSheetReader(sheet string) *xlsxWorksheet { } ok := f.checked[name] if !ok { + checkSheet(&xlsx) checkRow(&xlsx) f.checked[name] = true } @@ -226,7 +227,9 @@ func completeCol(xlsx *xlsxWorksheet, row int, cell int) { } } -// Completion row element tags of XML in a sheet. +// completeRow provides function to check and fill each column element for a +// single row and make that is continuous in a worksheet of XML by given row +// index and axis. func completeRow(xlsx *xlsxWorksheet, row, cell int) { currentRows := len(xlsx.SheetData.Row) if currentRows > 1 { @@ -235,6 +238,37 @@ func completeRow(xlsx *xlsxWorksheet, row, cell int) { row = lastRow } } + for i := currentRows; i < row; i++ { + xlsx.SheetData.Row = append(xlsx.SheetData.Row, xlsxRow{ + R: i + 1, + }) + } + buffer := bytes.Buffer{} + for ii := currentRows; ii < row; ii++ { + start := len(xlsx.SheetData.Row[ii].C) + if start == 0 { + for iii := start; iii < cell; iii++ { + 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(), + }) + buffer.Reset() + } + } + } +} + +// checkSheet provides function to fill each row element and make that is +// continuous in a worksheet of XML. +func checkSheet(xlsx *xlsxWorksheet) { + row := len(xlsx.SheetData.Row) + if row > 1 { + lastRow := xlsx.SheetData.Row[row-1].R + if lastRow >= row { + row = lastRow + } + } sheetData := xlsxSheetData{} existsRows := map[int]int{} for k, v := range xlsx.SheetData.Row { @@ -250,24 +284,11 @@ func completeRow(xlsx *xlsxWorksheet, row, cell int) { R: i + 1, }) } - buffer := bytes.Buffer{} - for ii := 0; ii < row; ii++ { - start := len(sheetData.Row[ii].C) - if start == 0 { - for iii := start; iii < cell; iii++ { - buffer.WriteString(toAlphaString(iii + 1)) - buffer.WriteString(strconv.Itoa(ii + 1)) - sheetData.Row[ii].C = append(sheetData.Row[ii].C, xlsxC{ - R: buffer.String(), - }) - buffer.Reset() - } - } - } xlsx.SheetData = sheetData } -// Replace xl/worksheets/sheet%d.xml XML tags to self-closing for compatible +// replaceWorkSheetsRelationshipsNameSpace provides function to replace +// xl/worksheets/sheet%d.xml XML tags to self-closing for compatible Microsoft // Office Excel 2007. func replaceWorkSheetsRelationshipsNameSpace(workbookMarshal string) string { oldXmlns := `` @@ -276,7 +297,8 @@ func replaceWorkSheetsRelationshipsNameSpace(workbookMarshal string) string { return workbookMarshal } -// Check XML tags and fix discontinuous case. For example: +// checkRow provides function to check and fill each column element for all rows +// and make that is continuous in a worksheet of XML. For example: // // //