From 9e8d36ce59381eadb934585a179c4c6d7f871b35 Mon Sep 17 00:00:00 2001 From: Ri Xu Date: Sat, 31 Dec 2016 23:47:30 +0800 Subject: [PATCH] - Performance improvement, remove `replaceRelationshipsID` and `workBookCompatibility` functions; - New functions `GetActiveSheetIndex`, `GetSheetName` and `GetSheetMap` added. --- excelize.go | 6 +- excelize_test.go | 6 ++ lib.go | 2 +- sheet.go | 119 +++++++++++------------ xmlWorkbook.go | 210 ++++++++++++++++++++++++---------------- xmlWorksheet.go | 244 +++++++++++++++++++++++++---------------------- 6 files changed, 320 insertions(+), 267 deletions(-) diff --git a/excelize.go b/excelize.go index af076fb..61391dc 100644 --- a/excelize.go +++ b/excelize.go @@ -82,7 +82,7 @@ func (f *File) SetCellInt(sheet string, axis string, value int) { xlsx.SheetData.Row[xAxis].C[yAxis].V = strconv.Itoa(value) output, _ := xml.Marshal(xlsx) - f.saveFileList(name, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output)))) + f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpace(string(output))) } // SetCellStr provide function to set string type value of a cell. @@ -107,7 +107,7 @@ func (f *File) SetCellStr(sheet string, axis string, value string) { xlsx.SheetData.Row[xAxis].C[yAxis].V = value output, _ := xml.Marshal(xlsx) - f.saveFileList(name, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output)))) + f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpace(string(output))) } // Completion column element tags of XML in a sheet. @@ -277,6 +277,6 @@ func (f *File) UpdateLinkedValue() { } } output, _ := xml.Marshal(xlsx) - f.saveFileList(name, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output)))) + f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpace(string(output))) } } diff --git a/excelize_test.go b/excelize_test.go index 35a395c..7848ed9 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -54,6 +54,12 @@ func TestExcelize(t *testing.T) { f1.SetCellValue("Sheet2", "M2", nil) // Test read cell value with given axis large than exists row. f1.GetCellValue("Sheet2", "E231") + // Test get active sheet of XLSX and get sheet name of XLSX by given sheet index. + f1.GetSheetName(f1.GetActiveSheetIndex()) + // Test get sheet name of XLSX by given invalid sheet index. + f1.GetSheetName(4) + // Test get sheet map of XLSX. + f1.GetSheetMap() for i := 1; i <= 300; i++ { f1.SetCellStr("SHEET3", "c"+strconv.Itoa(i), strconv.Itoa(i)) diff --git a/lib.go b/lib.go index 6ad3175..f24f25c 100644 --- a/lib.go +++ b/lib.go @@ -30,7 +30,7 @@ func ReadZipReader(r *zip.Reader) (map[string]string, int, error) { xml.Unmarshal([]byte(fileList[v.Name]), &xlsx) xlsx = checkRow(xlsx) output, _ := xml.Marshal(xlsx) - fileList[v.Name] = replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output))) + fileList[v.Name] = replaceWorkSheetsRelationshipsNameSpace(string(output)) worksheets++ } } diff --git a/sheet.go b/sheet.go index aa6844d..8338f14 100644 --- a/sheet.go +++ b/sheet.go @@ -8,55 +8,6 @@ import ( "strings" ) -// Define the empty element and self-close XML tags hack rules for -// xl/workbook.xml and xl/worksheets/sheet%d.xml. -var ( - WorkbookRules = []map[string]string{ - {`xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id="`: `r:id="`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - } - SheetRules = []map[string]string{ - {`xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id="`: `r:id="`}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {``: ``}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - {`>`: ` />`}, - } -) - // NewSheet provice function to greate a new sheet by given index, when // creating a new XLSX file, the default sheet will be create, when you // create a new file, you need to ensure that the index is continuous. @@ -100,7 +51,7 @@ func (f *File) setSheet(index int) { fmt.Println(err) } path := `xl/worksheets/sheet` + strconv.Itoa(index) + `.xml` - f.saveFileList(path, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output)))) + f.saveFileList(path, replaceWorkSheetsRelationshipsNameSpace(string(output))) } // Update workbook property of XLSX. Maximum 31 characters allowed in sheet title. @@ -119,7 +70,7 @@ func (f *File) setWorkbook(name string, rid int) { if err != nil { fmt.Println(err) } - f.saveFileList(`xl/workbook.xml`, workBookCompatibility(replaceRelationshipsNameSpace(string(output)))) + f.saveFileList(`xl/workbook.xml`, replaceRelationshipsNameSpace(string(output))) } // Read and unmarshal workbook relationships of XLSX. @@ -191,7 +142,7 @@ func (f *File) SetActiveSheet(index int) { if err != nil { fmt.Println(err) } - f.saveFileList(`xl/workbook.xml`, workBookCompatibility(replaceRelationshipsNameSpace(string(output)))) + f.saveFileList(`xl/workbook.xml`, replaceRelationshipsNameSpace(string(output))) index++ buffer := bytes.Buffer{} for i := 0; i < sheets; i++ { @@ -218,28 +169,66 @@ func (f *File) SetActiveSheet(index int) { if err != nil { fmt.Println(err) } - f.saveFileList(buffer.String(), replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(sheet)))) + f.saveFileList(buffer.String(), replaceWorkSheetsRelationshipsNameSpace(string(sheet))) buffer.Reset() } return } -// Replace xl/workbook.xml XML tags to self-closing for compatible Office Excel 2007. -func workBookCompatibility(workbookMarshal string) string { - for _, rules := range WorkbookRules { - for k, v := range rules { - workbookMarshal = strings.Replace(workbookMarshal, k, v, -1) +// GetActiveSheetIndex provide function to get active sheet of XLSX. If not found +// the active sheet will be return integer 0. +func (f *File) GetActiveSheetIndex() int { + content := xlsxWorkbook{} + buffer := bytes.Buffer{} + xml.Unmarshal([]byte(f.readXML(`xl/workbook.xml`)), &content) + for _, v := range content.Sheets.Sheet { + xlsx := xlsxWorksheet{} + buffer.WriteString(`xl/worksheets/sheet`) + buffer.WriteString(strings.TrimPrefix(v.ID, `rId`)) + buffer.WriteString(`.xml`) + xml.Unmarshal([]byte(f.readXML(buffer.String())), &xlsx) + for _, sheetView := range xlsx.SheetViews.SheetView { + if sheetView.TabSelected { + id, _ := strconv.Atoi(strings.TrimPrefix(v.ID, `rId`)) + return id + } } + buffer.Reset() } - return workbookMarshal + return 0 } -// replace relationships ID in worksheets/sheet%d.xml -func replaceRelationshipsID(workbookMarshal string) string { - for _, rules := range SheetRules { - for k, v := range rules { - workbookMarshal = strings.Replace(workbookMarshal, k, v, -1) +// GetSheetName provide function to get sheet name of XLSX by given sheet index. +// If given sheet index is invalid, will return an empty string. +func (f *File) GetSheetName(index int) string { + content := xlsxWorkbook{} + xml.Unmarshal([]byte(f.readXML(`xl/workbook.xml`)), &content) + for _, v := range content.Sheets.Sheet { + if v.ID == `rId`+strconv.Itoa(index) { + return v.Name } } - return workbookMarshal + return `` +} + +// GetSheetMap provide function to get sheet map of XLSX. For example: +// +// xlsx, err := excelize.OpenFile("/tmp/Workbook.xlsx") +// if err != nil { +// fmt.Println(err) +// os.Exit(1) +// } +// for k, v := range xlsx.GetSheetMap() +// fmt.Println(k, v) +// } +// +func (f *File) GetSheetMap() map[int]string { + content := xlsxWorkbook{} + sheetMap := map[int]string{} + xml.Unmarshal([]byte(f.readXML(`xl/workbook.xml`)), &content) + for _, v := range content.Sheets.Sheet { + id, _ := strconv.Atoi(strings.TrimPrefix(v.ID, `rId`)) + sheetMap[id] = v.Name + } + return sheetMap } diff --git a/xmlWorkbook.go b/xmlWorkbook.go index c196900..6ba7b53 100644 --- a/xmlWorkbook.go +++ b/xmlWorkbook.go @@ -1,5 +1,3 @@ -// Some code of this file reference tealeg/xlsx. - package excelize import "encoding/xml" @@ -13,7 +11,7 @@ const ( ) // xmlxWorkbookRels contains xmlxWorkbookRelations -// which maps sheet id and sheet XML +// which maps sheet id and sheet XML. type xlsxWorkbookRels struct { XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"` Relationships []xlsxWorkbookRelation `xml:"Relationship"` @@ -31,39 +29,61 @@ type xlsxWorkbookRelation struct { // currently I have not checked it for completeness - it does as much // as I need. type xlsxWorkbook struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main workbook"` - FileVersion xlsxFileVersion `xml:"fileVersion"` - WorkbookPr xlsxWorkbookPr `xml:"workbookPr"` - WorkbookProtection xlsxWorkbookProtection `xml:"workbookProtection"` - BookViews xlsxBookViews `xml:"bookViews"` - Sheets xlsxSheets `xml:"sheets"` - ExternalReferences xlsxExternalReferences `xml:"externalReferences"` - DefinedNames xlsxDefinedNames `xml:"definedNames"` - CalcPr xlsxCalcPr `xml:"calcPr"` - PivotCaches xlsxPivotCaches `xml:"pivotCaches"` - ExtLst xlsxExtLst `xml:"extLst"` - FileRecoveryPr xlsxFileRecoveryPr `xml:"fileRecoveryPr"` -} - -// xlsxFileRecoveryPr maps sheet recovery information. + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main workbook"` + FileVersion *xlsxFileVersion `xml:"fileVersion"` + WorkbookPr *xlsxWorkbookPr `xml:"workbookPr"` + WorkbookProtection *xlsxWorkbookProtection `xml:"workbookProtection"` + BookViews xlsxBookViews `xml:"bookViews"` + Sheets xlsxSheets `xml:"sheets"` + ExternalReferences *xlsxExternalReferences `xml:"externalReferences"` + DefinedNames *xlsxDefinedNames `xml:"definedNames"` + CalcPr *xlsxCalcPr `xml:"calcPr"` + PivotCaches *xlsxPivotCaches `xml:"pivotCaches"` + ExtLst *xlsxExtLst `xml:"extLst"` + FileRecoveryPr *xlsxFileRecoveryPr `xml:"fileRecoveryPr"` +} + +// xlsxFileRecoveryPr maps sheet recovery information. This element +// defines properties that track the state of the workbook file, such +// as whether the file was saved during a crash, or whether it should +// be opened in auto-recover mode. type xlsxFileRecoveryPr struct { - RepairLoad int `xml:"repairLoad,attr,omitempty"` -} - -// xlsxWorkbookProtection directly maps the workbookProtection element from the -// namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main -// - currently I have not checked it for completeness - it does as -// much as I need. + AutoRecover bool `xml:"autoRecover,attr,omitempty"` + CrashSave bool `xml:"crashSave,attr,omitempty"` + DataExtractLoad bool `xml:"dataExtractLoad,attr,omitempty"` + RepairLoad bool `xml:"repairLoad,attr,omitempty"` +} + +// xlsxWorkbookProtection directly maps the workbookProtection element. +// This element specifies options for protecting data in the workbook. +// Applications might use workbook protection to prevent anyone from +// accidentally changing, moving, or deleting important data. This +// protection can be ignored by applications which choose not to support +// this optional protection mechanism. +// When a password is to be hashed and stored in this element, it shall +// be hashed as defined below, starting from a UTF-16LE encoded string +// value. If there is a leading BOM character (U+FEFF) in the encoded +// password it is removed before hash calculation. type xlsxWorkbookProtection struct { - // We don't need this, yet. -} - -// xlsxFileVersion directly maps the fileVersion element from the -// namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main -// - currently I have not checked it for completeness - it does as -// much as I need. + LockRevision bool `xml:"lockRevision,attr,omitempty"` + LockStructure bool `xml:"lockStructure,attr,omitempty"` + LockWindows bool `xml:"lockWindows,attr,omitempty"` + RevisionsAlgorithmName string `xml:"revisionsAlgorithmName,attr,omitempty"` + RevisionsHashValue string `xml:"revisionsHashValue,attr,omitempty"` + RevisionsSaltValue string `xml:"revisionsSaltValue,attr,omitempty"` + RevisionsSpinCount int `xml:"revisionsSpinCount,attr,omitempty"` + WorkbookAlgorithmName string `xml:"workbookAlgorithmName,attr,omitempty"` + WorkbookHashValue string `xml:"workbookHashValue,attr,omitempty"` + WorkbookSaltValue string `xml:"workbookSaltValue,attr,omitempty"` + WorkbookSpinCount int `xml:"workbookSpinCount,attr,omitempty"` +} + +// xlsxFileVersion directly maps the fileVersion element. This element +// defines properties that track which version of the application accessed +// the data and source code contained in the file. type xlsxFileVersion struct { AppName string `xml:"appName,attr,omitempty"` + CodeName string `xml:"codeName,attr,omitempty"` LastEdited string `xml:"lastEdited,attr,omitempty"` LowestEdited string `xml:"lowestEdited,attr,omitempty"` RupBuild string `xml:"rupBuild,attr,omitempty"` @@ -71,45 +91,57 @@ type xlsxFileVersion struct { // xlsxWorkbookPr directly maps the workbookPr element from the // namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main -// - currently I have not checked it for completeness - it does as -// much as I need. +// This element defines a collection of workbook properties. type xlsxWorkbookPr struct { - DefaultThemeVersion string `xml:"defaultThemeVersion,attr,omitempty"` - BackupFile bool `xml:"backupFile,attr,omitempty"` - ShowObjects string `xml:"showObjects,attr,omitempty"` - Date1904 bool `xml:"date1904,attr,omitempty"` - CodeName string `xml:"codeName,attr,omitempty"` -} - -// xlsxBookViews directly maps the bookViews element from the -// namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main -// - currently I have not checked it for completeness - it does as -// much as I need. + AllowRefreshQuery bool `xml:"allowRefreshQuery,attr,omitempty"` + AutoCompressPictures bool `xml:"autoCompressPictures,attr,omitempty"` + BackupFile bool `xml:"backupFile,attr,omitempty"` + CheckCompatibility bool `xml:"checkCompatibility,attr,omitempty"` + CodeName string `xml:"codeName,attr,omitempty"` + Date1904 bool `xml:"date1904,attr,omitempty"` + DefaultThemeVersion string `xml:"defaultThemeVersion,attr,omitempty"` + FilterPrivacy bool `xml:"filterPrivacy,attr,omitempty"` + HidePivotFieldList bool `xml:"hidePivotFieldList,attr,omitempty"` + PromptedSolutions bool `xml:"promptedSolutions,attr,omitempty"` + PublishItems bool `xml:"publishItems,attr,omitempty"` + RefreshAllConnections bool `xml:"refreshAllConnections,attr,omitempty"` + SaveExternalLinkValues bool `xml:"saveExternalLinkValues,attr,omitempty"` + ShowBorderUnselectedTables bool `xml:"showBorderUnselectedTables,attr,omitempty"` + ShowInkAnnotation bool `xml:"showInkAnnotation,attr,omitempty"` + ShowObjects string `xml:"showObjects,attr,omitempty"` + ShowPivotChartFilter bool `xml:"showPivotChartFilter,attr,omitempty"` + UpdateLinks string `xml:"updateLinks,attr,omitempty"` +} + +// xlsxBookViews directly maps the bookViews element. This element specifies +// the collection of workbook views of the enclosing workbook. Each view can +// specify a window position, filter options, and other configurations. There +// is no limit on the number of workbook views that can be defined for a workbook. type xlsxBookViews struct { WorkBookView []xlsxWorkBookView `xml:"workbookView"` } // xlsxWorkBookView directly maps the workbookView element from the // namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main -// - currently I have not checked it for completeness - it does as -// much as I need. +// This element specifies a single Workbook view. type xlsxWorkBookView struct { - ActiveTab int `xml:"activeTab,attr,omitempty"` - FirstSheet int `xml:"firstSheet,attr,omitempty"` - ShowHorizontalScroll bool `xml:"showHorizontalScroll,attr,omitempty"` - ShowVerticalScroll bool `xml:"showVerticalScroll,attr,omitempty"` - ShowSheetTabs bool `xml:"showSheetTabs,attr,omitempty"` - TabRatio int `xml:"tabRatio,attr,omitempty"` - WindowHeight int `xml:"windowHeight,attr,omitempty"` - WindowWidth int `xml:"windowWidth,attr,omitempty"` - XWindow string `xml:"xWindow,attr,omitempty"` - YWindow string `xml:"yWindow,attr,omitempty"` + ActiveTab int `xml:"activeTab,attr,omitempty"` + AutoFilterDateGrouping bool `xml:"autoFilterDateGrouping,attr,omitempty"` + FirstSheet int `xml:"firstSheet,attr,omitempty"` + Minimized bool `xml:"minimized,attr,omitempty"` + ShowHorizontalScroll bool `xml:"showHorizontalScroll,attr,omitempty"` + ShowSheetTabs bool `xml:"showSheetTabs,attr,omitempty"` + ShowVerticalScroll bool `xml:"showVerticalScroll,attr,omitempty"` + TabRatio int `xml:"tabRatio,attr,omitempty"` + Visibility string `xml:"visibility,attr,omitempty"` + WindowHeight int `xml:"windowHeight,attr,omitempty"` + WindowWidth int `xml:"windowWidth,attr,omitempty"` + XWindow string `xml:"xWindow,attr,omitempty"` + YWindow string `xml:"yWindow,attr,omitempty"` } // xlsxSheets directly maps the sheets element from the namespace -// http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// http://schemas.openxmlformats.org/spreadsheetml/2006/main. type xlsxSheets struct { Sheet []xlsxSheet `xml:"sheet"` } @@ -162,47 +194,57 @@ type xlsxExtLst struct { Ext string `xml:",innerxml"` } -// xlsxDefinedNames directly maps the definedNames element from the -// namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main -// - currently I have not checked it for completeness - it does as -// much as I need. +// xlsxDefinedNames directly maps the definedNames element. This element +// defines the collection of defined names for this workbook. Defined +// names are descriptive names to represent cells, ranges of cells, +// formulas, or constant values. Defined names can be used to represent +// a range on any worksheet. type xlsxDefinedNames struct { DefinedName []xlsxDefinedName `xml:"definedName"` } // xlsxDefinedName directly maps the definedName element from the // namespace http://schemas.openxmlformats.org/spreadsheetml/2006/main -// - currently I have not checked it for completeness - it does as -// much as I need. -// for a descriptions of the attributes see -// https://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.definedname.aspx +// This element defines a defined name within this workbook. A defined +// name is descriptive text that is used to represents a cell, range of +// cells, formula, or constant value. For a descriptions of the attributes +// see https://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.definedname.aspx type xlsxDefinedName struct { - Data string `xml:",chardata"` - Name string `xml:"name,attr"` Comment string `xml:"comment,attr,omitempty"` CustomMenu string `xml:"customMenu,attr,omitempty"` Description string `xml:"description,attr,omitempty"` + Function bool `xml:"function,attr,omitempty"` + FunctionGroupID int `xml:"functionGroupId,attr,omitempty"` Help string `xml:"help,attr,omitempty"` + Hidden bool `xml:"hidden,attr,omitempty"` + LocalSheetID int `xml:"localSheetId,attr,omitempty"` + Name string `xml:"name,attr,omitempty"` + PublishToServer bool `xml:"publishToServer,attr,omitempty"` ShortcutKey string `xml:"shortcutKey,attr,omitempty"` StatusBar string `xml:"statusBar,attr,omitempty"` - LocalSheetID int `xml:"localSheetId,attr,omitempty"` - FunctionGroupID int `xml:"functionGroupId,attr,omitempty"` - Function bool `xml:"function,attr,omitempty"` - Hidden bool `xml:"hidden,attr,omitempty"` VbProcedure bool `xml:"vbProcedure,attr,omitempty"` - PublishToServer bool `xml:"publishToServer,attr,omitempty"` WorkbookParameter bool `xml:"workbookParameter,attr,omitempty"` Xlm bool `xml:"xml,attr,omitempty"` + Data string `xml:",chardata"` } -// xlsxCalcPr directly maps the calcPr element from the namespace -// http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// xlsxCalcPr directly maps the calcPr element. This element defines the +// collection of properties the application uses to record calculation +// status and details. Calculation is the process of computing formulas +// and then displaying the results as values in the cells that contain +// the formulas. type xlsxCalcPr struct { - CalcID string `xml:"calcId,attr,omitempty"` - IterateCount int `xml:"iterateCount,attr,omitempty"` - RefMode string `xml:"refMode,attr,omitempty"` - Iterate bool `xml:"iterate,attr,omitempty"` - IterateDelta float64 `xml:"iterateDelta,attr,omitempty"` + CalcCompleted bool `xml:"calcCompleted,attr,omitempty"` + CalcID string `xml:"calcId,attr,omitempty"` + CalcMode string `xml:"calcMode,attr,omitempty"` + CalcOnSave bool `xml:"calcOnSave,attr,omitempty"` + ConcurrentCalc bool `xml:"concurrentCalc,attr,omitempty"` + ConcurrentManualCount int `xml:"concurrentManualCount,attr,omitempty"` + ForceFullCalc bool `xml:"forceFullCalc,attr,omitempty"` + FullCalcOnLoad bool `xml:"fullCalcOnLoad,attr,omitempty"` + FullPrecision bool `xml:"fullPrecision,attr,omitempty"` + Iterate bool `xml:"iterate,attr,omitempty"` + IterateCount int `xml:"iterateCount,attr,omitempty"` + IterateDelta float64 `xml:"iterateDelta,attr,omitempty"` + RefMode string `xml:"refMode,attr,omitempty"` } diff --git a/xmlWorksheet.go b/xmlWorksheet.go index 0c5494d..509214e 100644 --- a/xmlWorksheet.go +++ b/xmlWorksheet.go @@ -1,5 +1,3 @@ -// Some code of this file reference tealeg/xlsx. - package excelize import "encoding/xml" @@ -9,26 +7,26 @@ import "encoding/xml" // currently I have not checked it for completeness - it does as much // as I need. type xlsxWorksheet struct { - XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main worksheet"` - SheetPr xlsxSheetPr `xml:"sheetPr"` - Dimension xlsxDimension `xml:"dimension"` - SheetViews xlsxSheetViews `xml:"sheetViews"` - SheetFormatPr xlsxSheetFormatPr `xml:"sheetFormatPr"` - Cols *xlsxCols `xml:"cols,omitempty"` - SheetData xlsxSheetData `xml:"sheetData"` - SheetProtection xlsxSheetProtection `xml:"sheetProtection"` - MergeCells *xlsxMergeCells `xml:"mergeCells,omitempty"` - ConditionalFormatting xlsxConditionalFormatting `xml:"conditionalFormatting"` - Hyperlinks xlsxHyperlinks `xml:"hyperlinks"` - PrintOptions xlsxPrintOptions `xml:"printOptions"` - PageMargins xlsxPageMargins `xml:"pageMargins"` - PageSetUp xlsxPageSetUp `xml:"pageSetup"` - HeaderFooter xlsxHeaderFooter `xml:"headerFooter"` - Drawing xlsxDrawing `xml:"drawing"` - LegacyDrawing xlsxLegacyDrawing `xml:"legacyDrawing"` - Picture xlsxPicture `xml:"picture"` - TableParts xlsxTableParts `xml:"tableParts"` - ExtLst xlsxExtLst `xml:"extLst"` + XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main worksheet"` + SheetPr *xlsxSheetPr `xml:"sheetPr"` + Dimension xlsxDimension `xml:"dimension"` + SheetViews xlsxSheetViews `xml:"sheetViews"` + SheetFormatPr *xlsxSheetFormatPr `xml:"sheetFormatPr"` + Cols *xlsxCols `xml:"cols,omitempty"` + SheetData xlsxSheetData `xml:"sheetData"` + SheetProtection *xlsxSheetProtection `xml:"sheetProtection"` + MergeCells *xlsxMergeCells `xml:"mergeCells,omitempty"` + ConditionalFormatting *xlsxConditionalFormatting `xml:"conditionalFormatting"` + Hyperlinks *xlsxHyperlinks `xml:"hyperlinks"` + PrintOptions *xlsxPrintOptions `xml:"printOptions"` + PageMargins *xlsxPageMargins `xml:"pageMargins"` + PageSetUp *xlsxPageSetUp `xml:"pageSetup"` + HeaderFooter *xlsxHeaderFooter `xml:"headerFooter"` + Drawing *xlsxDrawing `xml:"drawing"` + LegacyDrawing *xlsxLegacyDrawing `xml:"legacyDrawing"` + Picture *xlsxPicture `xml:"picture"` + TableParts *xlsxTableParts `xml:"tableParts"` + ExtLst *xlsxExtLst `xml:"extLst"` } // xlsxDrawing change r:id to rid in the namespace. @@ -38,13 +36,17 @@ type xlsxDrawing struct { // xlsxHeaderFooter directly maps the headerFooter element in the namespace // http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// When printed or viewed in page layout view (ยง18.18.69), each page of a +// worksheet can have a page header, a page footer, or both. The headers and +// footers on odd-numbered pages can differ from those on even-numbered pages, +// and the headers and footers on the first page can differ from those on odd- +// and even-numbered pages. In the latter case, the first page is not considered +// an odd page. type xlsxHeaderFooter struct { - DifferentFirst bool `xml:"differentFirst,attr"` - DifferentOddEven bool `xml:"differentOddEven,attr"` - OddHeader []xlsxOddHeader `xml:"oddHeader"` - OddFooter []xlsxOddFooter `xml:"oddFooter"` + DifferentFirst bool `xml:"differentFirst,attr,omitempty"` + DifferentOddEven bool `xml:"differentOddEven,attr,omitempty"` + OddHeader []*xlsxOddHeader `xml:"oddHeader"` + OddFooter []*xlsxOddFooter `xml:"oddFooter"` } // xlsxOddHeader directly maps the oddHeader element in the namespace @@ -65,49 +67,51 @@ type xlsxOddFooter struct { // xlsxPageSetUp directly maps the pageSetup element in the namespace // http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// Page setup settings for the worksheet. type xlsxPageSetUp struct { - PaperSize string `xml:"paperSize,attr,omitempty"` - Scale int `xml:"scale,attr"` - FirstPageNumber int `xml:"firstPageNumber,attr"` - FitToWidth int `xml:"fitToWidth,attr"` - FitToHeight int `xml:"fitToHeight,attr"` - PageOrder string `xml:"pageOrder,attr,omitempty"` - Orientation string `xml:"orientation,attr,omitempty"` - UsePrinterDefaults bool `xml:"usePrinterDefaults,attr"` - BlackAndWhite bool `xml:"blackAndWhite,attr"` - Draft bool `xml:"draft,attr"` + BlackAndWhite bool `xml:"blackAndWhite,attr,omitempty"` CellComments string `xml:"cellComments,attr,omitempty"` - UseFirstPageNumber bool `xml:"useFirstPageNumber,attr"` - HorizontalDPI float32 `xml:"horizontalDpi,attr"` - VerticalDPI float32 `xml:"verticalDpi,attr"` - Copies int `xml:"copies,attr"` + Copies int `xml:"copies,attr,omitempty"` + Draft bool `xml:"draft,attr,omitempty"` + Errors string `xml:"errors,attr,omitempty"` + FirstPageNumber int `xml:"firstPageNumber,attr,omitempty"` + FitToHeight int `xml:"fitToHeight,attr,omitempty"` + FitToWidth int `xml:"fitToWidth,attr,omitempty"` + HorizontalDPI float32 `xml:"horizontalDpi,attr,omitempty"` + RID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"` + Orientation string `xml:"orientation,attr,omitempty"` + PageOrder string `xml:"pageOrder,attr,omitempty"` + paperHeight string `xml:"paperHeight,attr,omitempty"` + PaperSize string `xml:"paperSize,attr,omitempty"` + PaperWidth string `xml:"paperWidth,attr,omitempty"` + Scale int `xml:"scale,attr,omitempty"` + UseFirstPageNumber bool `xml:"useFirstPageNumber,attr,omitempty"` + UsePrinterDefaults bool `xml:"usePrinterDefaults,attr,omitempty"` + VerticalDPI float32 `xml:"verticalDpi,attr,omitempty"` } // xlsxPrintOptions directly maps the printOptions element in the namespace // http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// Print options for the sheet. Printer-specific settings are stored separately +// in the Printer Settings part. type xlsxPrintOptions struct { - Headings bool `xml:"headings,attr"` - GridLines bool `xml:"gridLines,attr"` - GridLinesSet bool `xml:"gridLinesSet,attr"` - HorizontalCentered bool `xml:"horizontalCentered,attr"` - VerticalCentered bool `xml:"verticalCentered,attr"` + GridLines bool `xml:"gridLines,attr,omitempty"` + GridLinesSet bool `xml:"gridLinesSet,attr,omitempty"` + Headings bool `xml:"headings,attr,omitempty"` + HorizontalCentered bool `xml:"horizontalCentered,attr,omitempty"` + VerticalCentered bool `xml:"verticalCentered,attr,omitempty"` } // xlsxPageMargins directly maps the pageMargins element in the namespace // http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// Page margins for a sheet or a custom sheet view. type xlsxPageMargins struct { + Bottom float64 `xml:"bottom,attr"` + Footer float64 `xml:"footer,attr"` + Header float64 `xml:"header,attr"` Left float64 `xml:"left,attr"` Right float64 `xml:"right,attr"` Top float64 `xml:"top,attr"` - Bottom float64 `xml:"bottom,attr"` - Header float64 `xml:"header,attr"` - Footer float64 `xml:"footer,attr"` } // xlsxSheetFormatPr directly maps the sheetFormatPr element in the namespace @@ -125,8 +129,7 @@ type xlsxSheetFormatPr struct { // xlsxSheetViews directly maps the sheetViews element in the namespace // http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// Worksheet views collection. type xlsxSheetViews struct { SheetView []xlsxSheetView `xml:"sheetView"` } @@ -145,68 +148,68 @@ type xlsxSheetViews struct { // windows are viewing the same sheet, multiple sheetView elements // (with corresponding workbookView entries) are saved. type xlsxSheetView struct { - WindowProtection bool `xml:"windowProtection,attr,omitempty"` - ShowFormulas bool `xml:"showFormulas,attr,omitempty"` - ShowGridLines string `xml:"showGridLines,attr,omitempty"` - ShowRowColHeaders bool `xml:"showRowColHeaders,attr,omitempty"` - ShowZeros bool `xml:"showZeros,attr,omitempty"` - RightToLeft bool `xml:"rightToLeft,attr,omitempty"` - TabSelected bool `xml:"tabSelected,attr,omitempty"` - ShowOutlineSymbols bool `xml:"showOutlineSymbols,attr,omitempty"` - DefaultGridColor bool `xml:"defaultGridColor,attr"` - View string `xml:"view,attr,omitempty"` - TopLeftCell string `xml:"topLeftCell,attr,omitempty"` - ColorId int `xml:"colorId,attr,omitempty"` - ZoomScale float64 `xml:"zoomScale,attr,omitempty"` - ZoomScaleNormal float64 `xml:"zoomScaleNormal,attr,omitempty"` - ZoomScalePageLayoutView float64 `xml:"zoomScalePageLayoutView,attr,omitempty"` - WorkbookViewID int `xml:"workbookViewId,attr"` - Pane *xlsxPane `xml:"pane,omitempty"` - Selection []xlsxSelection `xml:"selection"` + WindowProtection bool `xml:"windowProtection,attr,omitempty"` + ShowFormulas bool `xml:"showFormulas,attr,omitempty"` + ShowGridLines string `xml:"showGridLines,attr,omitempty"` + ShowRowColHeaders bool `xml:"showRowColHeaders,attr,omitempty"` + ShowZeros bool `xml:"showZeros,attr,omitempty"` + RightToLeft bool `xml:"rightToLeft,attr,omitempty"` + TabSelected bool `xml:"tabSelected,attr,omitempty"` + ShowOutlineSymbols bool `xml:"showOutlineSymbols,attr,omitempty"` + DefaultGridColor bool `xml:"defaultGridColor,attr"` + View string `xml:"view,attr,omitempty"` + TopLeftCell string `xml:"topLeftCell,attr,omitempty"` + ColorID int `xml:"colorId,attr,omitempty"` + ZoomScale float64 `xml:"zoomScale,attr,omitempty"` + ZoomScaleNormal float64 `xml:"zoomScaleNormal,attr,omitempty"` + ZoomScalePageLayoutView float64 `xml:"zoomScalePageLayoutView,attr,omitempty"` + WorkbookViewID int `xml:"workbookViewId,attr"` + Pane *xlsxPane `xml:"pane,omitempty"` + Selection []*xlsxSelection `xml:"selection"` } // xlsxSelection directly maps the selection element in the namespace // http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// Worksheet view selection. type xlsxSelection struct { - Pane string `xml:"pane,attr,omitempty"` ActiveCell string `xml:"activeCell,attr,omitempty"` ActiveCellID int `xml:"activeCellId,attr"` + Pane string `xml:"pane,attr,omitempty"` SQRef string `xml:"sqref,attr,omitempty"` } -// xlsxSelection directly maps the selection element in the namespace -// http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// xlsxSelection directly maps the selection element. +// Worksheet view pane. type xlsxPane struct { - XSplit float64 `xml:"xSplit,attr"` - YSplit float64 `xml:"ySplit,attr"` - TopLeftCell string `xml:"topLeftCell,attr,omitempty"` ActivePane string `xml:"activePane,attr,omitempty"` State string `xml:"state,attr,omitempty"` // Either "split" or "frozen" + TopLeftCell string `xml:"topLeftCell,attr,omitempty"` + XSplit float64 `xml:"xSplit,attr,omitempty"` + YSplit float64 `xml:"ySplit,attr,omitempty"` } // xlsxSheetPr directly maps the sheetPr element in the namespace // http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// Sheet-level properties. type xlsxSheetPr struct { - XMLName xml.Name `xml:"sheetPr"` - FilterMode bool `xml:"filterMode,attr,omitempty"` - CodeName string `xml:"codeName,attr,omitempty"` - EnableFormatConditionsCalculation int `xml:"enableFormatConditionsCalculation,attr,omitempty"` - TabColor xlsxTabColor `xml:"tabColor,omitempty"` - PageSetUpPr xlsxPageSetUpPr `xml:"pageSetUpPr"` + XMLName xml.Name `xml:"sheetPr"` + CodeName string `xml:"codeName,attr,omitempty"` + EnableFormatConditionsCalculation bool `xml:"enableFormatConditionsCalculation,attr,omitempty"` + FilterMode bool `xml:"filterMode,attr,omitempty"` + Published bool `xml:"published,attr,omitempty"` + SyncHorizontal bool `xml:"syncHorizontal,attr,omitempty"` + SyncVertical bool `xml:"syncVertical,attr,omitempty"` + TransitionEntry bool `xml:"transitionEntry,attr,omitempty"` + TabColor *xlsxTabColor `xml:"tabColor,omitempty"` + PageSetUpPr *xlsxPageSetUpPr `xml:"pageSetUpPr,omitempty"` } // xlsxPageSetUpPr directly maps the pageSetupPr element in the namespace // http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// Page setup properties of the worksheet. type xlsxPageSetUpPr struct { - FitToPage bool `xml:"fitToPage,attr"` // Flag indicating whether the Fit to Page print option is enabled. + AutoPageBreaks bool `xml:"autoPageBreaks,attr,omitempty"` + FitToPage bool `xml:"fitToPage,attr,omitempty"` // Flag indicating whether the Fit to Page print option is enabled. } // xlsxTabColor directly maps the tabColor element in the namespace @@ -242,8 +245,11 @@ type xlsxCol struct { // xlsxDimension directly maps the dimension element in the namespace // http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// This element specifies the used range of the worksheet. It specifies +// the row and column bounds of used cells in the worksheet. This is +// optional and is not required. Used cells include cells with formulas, +// text content, and cell formatting. When an entire column is formatted, +// only the first cell in that column is considered used. type xlsxDimension struct { Ref string `xml:"ref,attr"` } @@ -257,28 +263,35 @@ type xlsxSheetData struct { Row []xlsxRow `xml:"row"` } -// xlsxRow directly maps the row element in the namespace -// http://schemas.openxmlformats.org/spreadsheetml/2006/main - -// currently I have not checked it for completeness - it does as much -// as I need. +// xlsxRow directly maps the row element. The element expresses information +// about an entire row of a worksheet, and contains all cell definitions for +// a particular row in the worksheet. type xlsxRow struct { - R int `xml:"r,attr"` - Spans string `xml:"spans,attr,omitempty"` + Collapsed bool `xml:"collapsed,attr,omitempty"` + CustomFormat bool `xml:"customFormat,attr,omitempty"` + CustomHeight bool `xml:"customHeight,attr,omitempty"` Hidden bool `xml:"hidden,attr,omitempty"` - C []xlsxC `xml:"c"` Ht string `xml:"ht,attr,omitempty"` - CustomHeight bool `xml:"customHeight,attr,omitempty"` OutlineLevel uint8 `xml:"outlineLevel,attr,omitempty"` + Ph bool `xml:"ph,attr,omitempty"` + R int `xml:"r,attr,omitempty"` + S int `xml:"s,attr,omitempty"` + Spans string `xml:"spans,attr,omitempty"` + ThickBot bool `xml:"thickBot,attr,omitempty"` + ThickTop bool `xml:"thickTop,attr,omitempty"` + C []xlsxC `xml:"c"` } +// xlsxMergeCell directly maps the mergeCell element. A single merged cell. type xlsxMergeCell struct { - Ref string `xml:"ref,attr"` // ref: horiz "A1:C1", vert "B3:B6", both "D3:G4" + Ref string `xml:"ref,attr,omitempty"` // ref: horiz "A1:C1", vert "B3:B6", both "D3:G4" } +// xlsxMergeCells directly maps the mergeCells element. This collection expresses +// all the merged cells in the sheet. type xlsxMergeCells struct { - XMLName xml.Name //`xml:"mergeCells,omitempty"` - Count int `xml:"count,attr,omitempty"` - Cells []xlsxMergeCell `xml:"mergeCell,omitempty"` + Count int `xml:"count,attr,omitempty"` + Cells []*xlsxMergeCell `xml:"mergeCell,omitempty"` } // xlsxC directly maps the c element in the namespace @@ -339,7 +352,10 @@ type xlsxConditionalFormatting struct { } // xlsxHyperlinks directly maps the hyperlinks element in the namespace -// http://schemas.openxmlformats.org/spreadsheetml/2006/main +// http://schemas.openxmlformats.org/spreadsheetml/2006/main - +// A hyperlink can be stored in a package as a relationship. Hyperlinks +// shall be identified by containing a target which specifies the +// destination of the given hyperlink. type xlsxHyperlinks struct { Hyperlink []xlsxHyperlink `xml:"hyperlink"` } @@ -388,8 +404,8 @@ type xlsxHyperlink struct { // // type xlsxTableParts struct { - Count int `xml:"count,attr"` - TableParts []xlsxTablePart `xml:"tablePart"` + Count int `xml:"count,attr,omitempty"` + TableParts []*xlsxTablePart `xml:"tablePart"` } // xlsxTablePart directly maps the tablePart element in the namespace -- GitLab