🎉 Initial commit
This commit is contained in:
214
workbook/workbook.go
Normal file
214
workbook/workbook.go
Normal file
@@ -0,0 +1,214 @@
|
||||
package workbook
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Workbook 表示一个Excel工作簿
|
||||
type Workbook struct {
|
||||
Worksheets []*Worksheet
|
||||
Properties *WorkbookProperties
|
||||
Relationships *Relationships
|
||||
Styles *Styles
|
||||
Theme *Theme
|
||||
ContentTypes *ContentTypes
|
||||
Rels *WorkbookRels
|
||||
SharedStrings *SharedStrings
|
||||
}
|
||||
|
||||
// WorkbookProperties 包含工作簿的元数据
|
||||
type WorkbookProperties struct {
|
||||
Title string
|
||||
Subject string
|
||||
Creator string
|
||||
Keywords string
|
||||
Description string
|
||||
LastModifiedBy string
|
||||
Revision int
|
||||
Created time.Time
|
||||
Modified time.Time
|
||||
}
|
||||
|
||||
// NewWorkbook 创建一个新的Excel工作簿
|
||||
func NewWorkbook() *Workbook {
|
||||
return &Workbook{
|
||||
Worksheets: make([]*Worksheet, 0),
|
||||
Properties: &WorkbookProperties{
|
||||
Created: time.Now(),
|
||||
Modified: time.Now(),
|
||||
Revision: 1,
|
||||
},
|
||||
Relationships: NewRelationships(),
|
||||
Styles: NewStyles(),
|
||||
Theme: NewTheme(),
|
||||
ContentTypes: NewContentTypes(),
|
||||
Rels: NewWorkbookRels(),
|
||||
SharedStrings: NewSharedStrings(),
|
||||
}
|
||||
}
|
||||
|
||||
// AddWorksheet 添加一个新的工作表
|
||||
func (wb *Workbook) AddWorksheet(name string) *Worksheet {
|
||||
ws := NewWorksheet(name)
|
||||
ws.SheetID = len(wb.Worksheets) + 1
|
||||
wb.Worksheets = append(wb.Worksheets, ws)
|
||||
return ws
|
||||
}
|
||||
|
||||
// Save 保存Excel工作簿到文件
|
||||
func (wb *Workbook) Save(filename string) error {
|
||||
// 创建一个新的zip文件
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 创建一个新的zip writer
|
||||
zipWriter := zip.NewWriter(file)
|
||||
defer zipWriter.Close()
|
||||
|
||||
// 添加[Content_Types].xml
|
||||
contentTypesWriter, err := zipWriter.Create("[Content_Types].xml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = contentTypesWriter.Write([]byte(wb.ContentTypes.ToXML()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 添加_rels/.rels
|
||||
relsDir, err := zipWriter.Create("_rels/.rels")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建根关系
|
||||
rootRels := NewRelationships()
|
||||
rootRels.AddRelationship("rId1", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", "xl/workbook.xml")
|
||||
_, err = relsDir.Write([]byte(rootRels.ToXML()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 添加xl/workbook.xml
|
||||
workbookWriter, err := zipWriter.Create("xl/workbook.xml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = workbookWriter.Write([]byte(wb.ToXML()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 添加xl/_rels/workbook.xml.rels
|
||||
workbookRelsWriter, err := zipWriter.Create("xl/_rels/workbook.xml.rels")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建工作簿关系
|
||||
wbRels := NewRelationships()
|
||||
|
||||
// 添加样式关系
|
||||
wbRels.AddRelationship("rId1", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", "styles.xml")
|
||||
|
||||
// 添加主题关系
|
||||
wbRels.AddRelationship("rId2", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", "theme/theme1.xml")
|
||||
|
||||
// 添加共享字符串表关系
|
||||
wbRels.AddRelationship("rId3", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", "sharedStrings.xml")
|
||||
|
||||
// 添加工作表关系
|
||||
for i := range wb.Worksheets {
|
||||
relID := fmt.Sprintf("rId%d", i+4) // 从rId4开始
|
||||
target := fmt.Sprintf("worksheets/sheet%d.xml", i+1)
|
||||
wbRels.AddRelationship(relID, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", target)
|
||||
}
|
||||
|
||||
_, err = workbookRelsWriter.Write([]byte(wbRels.ToXML()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 添加xl/worksheets/sheet1.xml, sheet2.xml, ...
|
||||
for i, ws := range wb.Worksheets {
|
||||
sheetPath := fmt.Sprintf("xl/worksheets/sheet%d.xml", i+1)
|
||||
sheetWriter, err := zipWriter.Create(sheetPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = sheetWriter.Write([]byte(ws.ToXML(wb.SharedStrings)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 添加xl/styles.xml
|
||||
stylesWriter, err := zipWriter.Create("xl/styles.xml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = stylesWriter.Write([]byte(wb.Styles.ToXML()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 添加xl/theme/theme1.xml
|
||||
themeWriter, err := zipWriter.Create("xl/theme/theme1.xml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = themeWriter.Write([]byte(wb.Theme.ToXML()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 添加xl/sharedStrings.xml
|
||||
sharedStringsWriter, err := zipWriter.Create("xl/sharedStrings.xml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = sharedStringsWriter.Write([]byte(wb.SharedStrings.ToXML()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WorkbookRels 表示工作簿的关系
|
||||
type WorkbookRels struct {
|
||||
Relationships *Relationships
|
||||
}
|
||||
|
||||
// NewWorkbookRels 创建一个新的工作簿关系
|
||||
func NewWorkbookRels() *WorkbookRels {
|
||||
return &WorkbookRels{
|
||||
Relationships: NewRelationships(),
|
||||
}
|
||||
}
|
||||
|
||||
// ToXML 将工作簿转换为XML
|
||||
func (wb *Workbook) ToXML() string {
|
||||
xml := "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
||||
xml += "<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n"
|
||||
|
||||
// 工作簿属性
|
||||
xml += " <workbookPr defaultThemeVersion=\"124226\"/>\n"
|
||||
|
||||
// 工作表
|
||||
xml += " <sheets>\n"
|
||||
for i, ws := range wb.Worksheets {
|
||||
relID := fmt.Sprintf("rId%d", i+4) // 从rId4开始,与上面的关系ID对应
|
||||
xml += fmt.Sprintf(" <sheet name=\"%s\" sheetId=\"%d\" r:id=\"%s\"/>\n", ws.Name, ws.SheetID, relID)
|
||||
}
|
||||
xml += " </sheets>\n"
|
||||
|
||||
xml += "</workbook>"
|
||||
return xml
|
||||
}
|
Reference in New Issue
Block a user