summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--excelize.go9
-rw-r--r--lib.go7
-rw-r--r--sheet.go96
-rw-r--r--xmlWorksheet.go73
4 files changed, 121 insertions, 64 deletions
diff --git a/excelize.go b/excelize.go
index 86e2d99..af076fb 100644
--- a/excelize.go
+++ b/excelize.go
@@ -183,15 +183,6 @@ func replaceWorkSheetsRelationshipsNameSpace(workbookMarshal string) string {
oldXmlns := `<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`
newXmlns := `<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mx="http://schemas.microsoft.com/office/mac/excel/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:xm="http://schemas.microsoft.com/office/excel/2006/main">`
workbookMarshal = strings.Replace(workbookMarshal, oldXmlns, newXmlns, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></tablePart>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></dimension>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></selection>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></sheetFormatPr>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></printOptions>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></pageSetup>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></pageMargins>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></mergeCell>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></drawing>`, ` />`, -1)
return workbookMarshal
}
diff --git a/lib.go b/lib.go
index 03fc8f2..6ad3175 100644
--- a/lib.go
+++ b/lib.go
@@ -7,7 +7,6 @@ import (
"io"
"log"
"math"
- "strings"
)
// ReadZip takes a pointer to a zip.ReadCloser and returns a
@@ -28,7 +27,7 @@ func ReadZipReader(r *zip.Reader) (map[string]string, int, error) {
if len(v.Name) > 18 {
if v.Name[0:19] == `xl/worksheets/sheet` {
var xlsx xlsxWorksheet
- xml.Unmarshal([]byte(strings.Replace(fileList[v.Name], `<drawing r:id=`, `<drawing rid=`, -1)), &xlsx)
+ xml.Unmarshal([]byte(fileList[v.Name]), &xlsx)
xlsx = checkRow(xlsx)
output, _ := xml.Marshal(xlsx)
fileList[v.Name] = replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output)))
@@ -39,10 +38,10 @@ func ReadZipReader(r *zip.Reader) (map[string]string, int, error) {
return fileList, worksheets, nil
}
-// Read XML content as string and replace drawing property in XML namespace of sheet.
+// Read XML content as string.
func (f *File) readXML(name string) string {
if content, ok := f.XLSX[name]; ok {
- return strings.Replace(content, `<drawing r:id=`, `<drawing rid=`, -1)
+ return content
}
return ``
}
diff --git a/sheet.go b/sheet.go
index 16b9a60..aa6844d 100644
--- a/sheet.go
+++ b/sheet.go
@@ -8,6 +8,55 @@ 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="`},
+ {`></sheet>`: ` />`},
+ {`></workbookView>`: ` />`},
+ {`></fileVersion>`: ` />`},
+ {`></workbookPr>`: ` />`},
+ {`></calcPr>`: ` />`},
+ {`></workbookProtection>`: ` />`},
+ {`></fileRecoveryPr>`: ` />`},
+ {`></hyperlink>`: ` />`},
+ {`></tabColor>`: ` />`},
+ {`></pageSetUpPr>`: ` />`},
+ {`></pane>`: ` />`},
+ {`<extLst></extLst>`: ``},
+ {`<fileRecoveryPr />`: ``},
+ {`<workbookProtection />`: ``},
+ {`<pivotCaches></pivotCaches>`: ``},
+ {`<externalReferences></externalReferences>`: ``},
+ {`<workbookProtection></workbookProtection>`: ``},
+ {`<definedNames></definedNames>`: ``},
+ {`<fileRecoveryPr></fileRecoveryPr>`: ``},
+ {`<workbookPr />`: ``},
+ }
+ SheetRules = []map[string]string{
+ {`xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id="`: `r:id="`},
+ {`<drawing></drawing>`: ``},
+ {`<drawing />`: ``},
+ {`<hyperlinks></hyperlinks>`: ``},
+ {`<tableParts count="0"></tableParts>`: ``},
+ {`<picture></picture>`: ``},
+ {`<legacyDrawing></legacyDrawing>`: ``},
+ {`<tabColor></tabColor>`: ``},
+ {`<sheetProtection></sheetProtection>`: ``},
+ {`<conditionalFormatting></conditionalFormatting>`: ``},
+ {`<extLst></extLst>`: ``},
+ {`></tablePart>`: ` />`},
+ {`></dimension>`: ` />`},
+ {`></selection>`: ` />`},
+ {`></sheetFormatPr>`: ` />`},
+ {`></printOptions>`: ` />`},
+ {`></pageSetup>`: ` />`},
+ {`></pageMargins>`: ` />`},
+ {`></mergeCell>`: ` />`},
+ }
+)
+
// 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.
@@ -122,17 +171,6 @@ func replaceRelationshipsNameSpace(workbookMarshal string) string {
return strings.Replace(workbookMarshal, oldXmlns, newXmlns, -1)
}
-// replace relationships ID in worksheets/sheet%d.xml
-func replaceRelationshipsID(workbookMarshal string) string {
- rids := strings.Replace(workbookMarshal, `<drawing rid="" />`, ``, -1)
- rids = strings.Replace(rids, `<hyperlinks></hyperlinks>`, ``, -1)
- rids = strings.Replace(rids, `<tableParts count="0"></tableParts>`, ``, -1)
- rids = strings.Replace(rids, `<picture></picture>`, ``, -1)
- rids = strings.Replace(rids, `<legacyDrawing></legacyDrawing>`, ``, -1)
- rids = strings.Replace(rids, `<tabColor></tabColor>`, ``, -1)
- return strings.Replace(rids, `<drawing rid="`, `<drawing r:id="`, -1)
-}
-
// SetActiveSheet provide function to set default active sheet of XLSX by given index.
func (f *File) SetActiveSheet(index int) {
var content xlsxWorkbook
@@ -188,26 +226,20 @@ func (f *File) SetActiveSheet(index int) {
// Replace xl/workbook.xml XML tags to self-closing for compatible Office Excel 2007.
func workBookCompatibility(workbookMarshal string) string {
- workbookMarshal = strings.Replace(workbookMarshal, `xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id="`, `r:id="`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></sheet>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></workbookView>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></fileVersion>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></workbookPr>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></calcPr>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></workbookProtection>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></fileRecoveryPr>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></hyperlink>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></tabColor>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></pageSetUpPr>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `></pane>`, ` />`, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `<extLst></extLst>`, ``, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `<fileRecoveryPr />`, ``, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `<workbookProtection />`, ``, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `<pivotCaches></pivotCaches>`, ``, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `<externalReferences></externalReferences>`, ``, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `<workbookProtection></workbookProtection>`, ``, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `<definedNames></definedNames>`, ``, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `<fileRecoveryPr></fileRecoveryPr>`, ``, -1)
- workbookMarshal = strings.Replace(workbookMarshal, `<workbookPr />`, ``, -1)
+ for _, rules := range WorkbookRules {
+ for k, v := range rules {
+ workbookMarshal = strings.Replace(workbookMarshal, k, v, -1)
+ }
+ }
+ return workbookMarshal
+}
+
+// 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)
+ }
+ }
return workbookMarshal
}
diff --git a/xmlWorksheet.go b/xmlWorksheet.go
index 4752a15..0c5494d 100644
--- a/xmlWorksheet.go
+++ b/xmlWorksheet.go
@@ -9,29 +9,31 @@ 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"`
- Hyperlinks xlsxHyperlinks `xml:"hyperlinks"`
- MergeCells *xlsxMergeCells `xml:"mergeCells,omitempty"`
- 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.
type xlsxDrawing struct {
- RID string `xml:"rid,attr"`
+ RID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
}
// xlsxHeaderFooter directly maps the headerFooter element in the namespace
@@ -303,6 +305,39 @@ type xlsxF struct {
Si string `xml:"si,attr,omitempty"` // Shared formula index
}
+// xlsxSheetProtection collection expresses the sheet protection options
+// to enforce when the sheet is protected.
+type xlsxSheetProtection struct {
+ AlgorithmName string `xml:"algorithmName,attr,omitempty"`
+ AutoFilter int `xml:"autoFilter,attr,omitempty"`
+ DeleteColumns int `xml:"deleteColumns,attr,omitempty"`
+ DeleteRows int `xml:"deleteRows,attr,omitempty"`
+ FormatCells int `xml:"formatCells,attr,omitempty"`
+ FormatColumns int `xml:"formatColumns,attr,omitempty"`
+ FormatRows int `xml:"formatRows,attr,omitempty"`
+ HashValue string `xml:"hashValue,attr,omitempty"`
+ InsertColumns int `xml:"insertColumns,attr,omitempty"`
+ InsertHyperlinks int `xml:"insertHyperlinks,attr,omitempty"`
+ InsertRows int `xml:"insertRows,attr,omitempty"`
+ Objects int `xml:"objects,attr,omitempty"`
+ PivotTables int `xml:"pivotTables,attr,omitempty"`
+ SaltValue string `xml:"saltValue,attr,omitempty"`
+ Scenarios int `xml:"scenarios,attr,omitempty"`
+ SelectLockedCells int `xml:"selectLockedCells,attr,omitempty"`
+ SelectUnlockedCell int `xml:"selectUnlockedCell,attr,omitempty"`
+ Sheet int `xml:"sheet,attr,omitempty"`
+ Sort int `xml:"sort,attr,omitempty"`
+ SpinCount int `xml:"spinCount,attr,omitempty"`
+}
+
+// A Conditional Format is a format, such as cell shading or font color,
+// that a spreadsheet application can automatically apply to cells if a
+// specified condition is true. This collection expresses conditional
+// formatting rules applied to a particular cell or range.
+type xlsxConditionalFormatting struct {
+ CfRule string `xml:",innerxml"`
+}
+
// xlsxHyperlinks directly maps the hyperlinks element in the namespace
// http://schemas.openxmlformats.org/spreadsheetml/2006/main
type xlsxHyperlinks struct {