Browse Source

Include [Content_Types].xml in marshalled file output.

Geoffrey J. Teale 11 years ago
parent
commit
881db0c5ad
4 changed files with 72 additions and 15 deletions
  1. 21 2
      contenttypes.go
  2. 20 2
      contenttypes_test.go
  3. 14 8
      file.go
  4. 17 3
      file_test.go

+ 21 - 2
contenttypes.go

@@ -5,12 +5,31 @@ import (
 )
 
 type xlsxTypes struct {
-	XMLName		xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/content-types Types"`
+	XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/content-types Types"`
 
 	Overrides []xlsxOverride `xml:"Override"`
 }
 
 type xlsxOverride struct {
-	PartName string	`xml:",attr"`
+	PartName    string `xml:",attr"`
 	ContentType string `xml:",attr"`
 }
+
+func MakeDefaultContentTypes() (types xlsxTypes) {
+	types.Overrides = make([]xlsxOverride, 7)
+	types.Overrides[0].PartName = "/_rels/.rels"
+	types.Overrides[0].ContentType = "application/vnd.openxmlformats-package.relationships+xml"
+	types.Overrides[1].PartName = "/docProps/app.xml"
+	types.Overrides[1].ContentType = "application/vnd.openxmlformats-officedocument.extended-properties+xml"
+	types.Overrides[2].PartName = "/docProps/core.xml"
+	types.Overrides[2].ContentType = "application/vnd.openxmlformats-package.core-properties+xml"
+	types.Overrides[3].PartName = "/xl/_rels/workbook.xml.rels"
+	types.Overrides[3].ContentType = "application/vnd.openxmlformats-package.relationships+xml"
+	types.Overrides[4].PartName = "/xl/sharedStrings.xml"
+	types.Overrides[4].ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"
+	types.Overrides[5].PartName = "/xl/styles.xml"
+	types.Overrides[5].ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"
+	types.Overrides[6].PartName = "/xl/workbook.xml"
+	types.Overrides[6].ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
+	return
+}

+ 20 - 2
contenttypes_test.go

@@ -5,11 +5,10 @@ import (
 	. "gopkg.in/check.v1"
 )
 
-type ContentTypesSuite struct {}
+type ContentTypesSuite struct{}
 
 var _ = Suite(&ContentTypesSuite{})
 
-
 func (l *ContentTypesSuite) TestMarshalContentTypes(c *C) {
 	var types xlsxTypes = xlsxTypes{}
 	types.Overrides = make([]xlsxOverride, 1)
@@ -24,3 +23,22 @@ func (l *ContentTypesSuite) TestMarshalContentTypes(c *C) {
 	c.Assert(stringOutput, Equals, expectedContentTypes)
 }
 
+func (l *ContentTypesSuite) TestMakeDefaultContentTypes(c *C) {
+	var types xlsxTypes = MakeDefaultContentTypes()
+	c.Assert(len(types.Overrides), Equals, 7)
+	c.Assert(types.Overrides[0].PartName, Equals, "/_rels/.rels")
+	c.Assert(types.Overrides[0].ContentType, Equals, "application/vnd.openxmlformats-package.relationships+xml")
+	c.Assert(types.Overrides[1].PartName, Equals, "/docProps/app.xml")
+	c.Assert(types.Overrides[1].ContentType, Equals, "application/vnd.openxmlformats-officedocument.extended-properties+xml")
+	c.Assert(types.Overrides[2].PartName, Equals, "/docProps/core.xml")
+	c.Assert(types.Overrides[2].ContentType, Equals, "application/vnd.openxmlformats-package.core-properties+xml")
+	c.Assert(types.Overrides[3].PartName, Equals, "/xl/_rels/workbook.xml.rels")
+	c.Assert(types.Overrides[3].ContentType, Equals, "application/vnd.openxmlformats-package.relationships+xml")
+	c.Assert(types.Overrides[4].PartName, Equals, "/xl/sharedStrings.xml")
+	c.Assert(types.Overrides[4].ContentType, Equals, "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml")
+	c.Assert(types.Overrides[5].PartName, Equals, "/xl/styles.xml")
+	c.Assert(types.Overrides[5].ContentType, Equals, "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml")
+	c.Assert(types.Overrides[6].PartName, Equals, "/xl/workbook.xml")
+	c.Assert(types.Overrides[6].ContentType, Equals, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml")
+
+}

+ 14 - 8
file.go

@@ -56,14 +56,6 @@ func (f *File) makeWorkbook() xlsxWorkbook {
 	return workbook
 }
 
-// 	for sheetName, sheet := range f.Sheets {
-		
-// 	}
-// 	body, err := xml.MarshalIndent(workbook, "  ", "  ")
-// 	if err != nil { return "", err }
-// 	return xml.Header + string(body), nil
-// }
-
 
 func (f *File) MarshallParts() (map[string]string, error) {
 	var parts map[string]string
@@ -71,6 +63,7 @@ func (f *File) MarshallParts() (map[string]string, error) {
 	var workbookRels WorkBookRels = make(WorkBookRels)
 	var err error
 	var workbook xlsxWorkbook
+	var types xlsxTypes = MakeDefaultContentTypes()
 
 	marshal := func(thing interface{}) (string, error) {
 		body, err := xml.MarshalIndent(thing, "  ", "  ")
@@ -90,6 +83,12 @@ func (f *File) MarshallParts() (map[string]string, error) {
 		rId := fmt.Sprintf("rId%d", sheetIndex)
 		sheetId := strconv.Itoa(sheetIndex)
 		sheetPath := fmt.Sprintf("worksheets/sheet%d.xml", sheetIndex)
+		partName := "xl/" + sheetPath
+		types.Overrides = append(
+			types.Overrides,
+			xlsxOverride{
+				PartName: partName,
+				ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"})
 		workbookRels[rId] = sheetPath
 		workbook.Sheets.Sheet[sheetIndex - 1] = xlsxSheet{
 			Name: sheetName,
@@ -134,9 +133,16 @@ func (f *File) MarshallParts() (map[string]string, error) {
 	workbookRels[sheetId] = sheetPath
 	sheetIndex++
 	xWRel := workbookRels.MakeXLSXWorkbookRels()
+
 	parts["xl/_rels/workbook.xml.rels"], err = marshal(xWRel)
 	if err != nil {
 		return parts, err
 	}
+
+	parts["[Content_Types].xml"], err = marshal(types)
+	if err != nil {
+		return parts, err
+	}
+
 	return parts, nil
 }

+ 17 - 3
file_test.go

@@ -1,4 +1,4 @@
- package xlsx
+package xlsx
 
 import (
 	"encoding/xml"
@@ -54,7 +54,7 @@ func (l *FileSuite) TestCreateSheet(c *C) {
 // Test that we can add a sheet to a File
 func (l *FileSuite) TestAddSheet(c *C) {
 	var f *File
-	
+
 	f = NewFile()
 	sheet := f.AddSheet("MySheet")
 	c.Assert(sheet, NotNil)
@@ -100,6 +100,7 @@ func (l *FileSuite) TestMarshalWorkbook(c *C) {
 	c.Assert(stringOutput, Equals, expectedWorkbook)
 }
 
+
 // Test that we can marshall a File to a collection of xml files
 func (l *FileSuite) TestMarshalFile(c *C) {
 	var f *File
@@ -114,7 +115,7 @@ func (l *FileSuite) TestMarshalFile(c *C) {
 	cell2.Value = "A cell!"
 	parts, err := f.MarshallParts()
 	c.Assert(err, IsNil)
-	c.Assert(len(parts), Equals, 8)
+	c.Assert(len(parts), Equals, 9)
 	expectedSheet := `<?xml version="1.0" encoding="UTF-8"?>
   <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
     <dimension ref="A1:A1"></dimension>
@@ -180,4 +181,17 @@ func (l *FileSuite) TestMarshalFile(c *C) {
   </workbook>`
 	c.Assert(parts["xl/workbook.xml"], Equals, expectedWorkbook)
 
+	expectedContentTypes := `<?xml version="1.0" encoding="UTF-8"?>
+  <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
+    <Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"></Override>
+    <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"></Override>
+    <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"></Override>
+    <Override PartName="/xl/_rels/workbook.xml.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"></Override>
+    <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"></Override>
+    <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"></Override>
+    <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"></Override>
+    <Override PartName="xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"></Override>
+    <Override PartName="xl/worksheets/sheet2.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"></Override>
+  </Types>`
+	c.Assert(parts["[Content_Types].xml"], Equals, expectedContentTypes)
 }