forked from p30928647/excelize
Init commit.
This commit is contained in:
commit
a9d3ee2869
|
@ -0,0 +1,79 @@
|
|||
* Excelize
|
||||
|
||||
![Excelize](./excelize.png "Excelize")
|
||||
|
||||
** Introduction
|
||||
Excelize is a library written in pure Golang and providing a set of function that allow you to write to and read from XLSX files.
|
||||
|
||||
|
||||
|
||||
** Basic Usage
|
||||
|
||||
*** Installation
|
||||
|
||||
```
|
||||
go get github.com/luxurioust/excelize
|
||||
```
|
||||
|
||||
*** Create XLSX files
|
||||
|
||||
Here is a minimal example usage that will create XLSX file.
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/luxurioust/excelize"
|
||||
)
|
||||
|
||||
func main() {
|
||||
xlsx := excelize.CreateFile()
|
||||
xlsx = excelize.NewSheet(xlsx, 2, "Sheet2")
|
||||
xlsx = excelize.NewSheet(xlsx, 3, "Sheet3")
|
||||
xlsx = excelize.SetCellInt(xlsx, "Sheet2", "A23", 10)
|
||||
xlsx = excelize.SetCellStr(xlsx, "Sheet3", "B20", "Hello")
|
||||
err := excelize.Save(xlsx, "~/Workbook.xlsx")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*** Writing XLSX files
|
||||
|
||||
The following constitutes the bare minimum required to write an XLSX document.
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/luxurioust/excelize"
|
||||
)
|
||||
|
||||
func main() {
|
||||
xlsx, err := excelize.Openxlsx("~/Workbook.xlsx")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
xlsx = excelize.SetCellInt(xlsx, "Sheet2", "B2", 100)
|
||||
xlsx = excelize.SetCellStr(xlsx, "Sheet2", "C11", "Hello")
|
||||
xlsx = excelize.NewSheet(xlsx, 3, "TestSheet")
|
||||
xlsx = excelize.SetCellInt(xlsx, "Sheet3", "A23", 10)
|
||||
xlsx = excelize.SetCellStr(xlsx, "Sheet3", "b230", "World")
|
||||
xlsx = excelize.SetActiveSheet(xlsx, 2)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
err = excelize.Save(xlsx, "~/Workbook.xlsx")
|
||||
}
|
||||
```
|
||||
|
||||
** Contributing
|
||||
|
||||
Contributions are welcome! Open a pull request to fix a bug, or open an issue to discuss a new feature or change.
|
||||
|
||||
** Licenses
|
||||
|
||||
This program is under the terms of the BSD 3-Clause License. See <https://opensource.org/licenses/BSD-3-Clause>.
|
|
@ -0,0 +1,196 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type FileList struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
// OpenFile() take the name of an XLSX file and returns a populated
|
||||
// xlsx.File struct for it.
|
||||
func OpenFile(filename string) (file []FileList, err error) {
|
||||
var f *zip.ReadCloser
|
||||
f, err = zip.OpenReader(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
file, err = ReadZip(f)
|
||||
return
|
||||
}
|
||||
|
||||
// Set int type value of a cell
|
||||
func SetCellInt(file []FileList, sheet string, axis string, value int) []FileList {
|
||||
axis = strings.ToUpper(axis)
|
||||
var xlsx xlsxWorksheet
|
||||
col := getColIndex(axis)
|
||||
row := getRowIndex(axis)
|
||||
xAxis := row - 1
|
||||
yAxis := titleToNumber(col)
|
||||
|
||||
name := fmt.Sprintf("xl/worksheets/%s.xml", strings.ToLower(sheet))
|
||||
xml.Unmarshal([]byte(readXml(file, name)), &xlsx)
|
||||
|
||||
rows := xAxis + 1
|
||||
cell := yAxis + 1
|
||||
|
||||
xlsx = checkRow(xlsx)
|
||||
|
||||
xlsx = completeRow(xlsx, rows, cell)
|
||||
xlsx = completeCol(xlsx, rows, cell)
|
||||
|
||||
xlsx.SheetData.Row[xAxis].C[yAxis].T = ""
|
||||
xlsx.SheetData.Row[xAxis].C[yAxis].V = strconv.Itoa(value)
|
||||
|
||||
output, err := xml.MarshalIndent(xlsx, "", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
saveFileList(file, name, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output))))
|
||||
return file
|
||||
}
|
||||
|
||||
// Set string type value of a cell
|
||||
func SetCellStr(file []FileList, sheet string, axis string, value string) []FileList {
|
||||
axis = strings.ToUpper(axis)
|
||||
var xlsx xlsxWorksheet
|
||||
col := getColIndex(axis)
|
||||
row := getRowIndex(axis)
|
||||
xAxis := row - 1
|
||||
yAxis := titleToNumber(col)
|
||||
|
||||
name := fmt.Sprintf("xl/worksheets/%s.xml", strings.ToLower(sheet))
|
||||
xml.Unmarshal([]byte(readXml(file, name)), &xlsx)
|
||||
|
||||
rows := xAxis + 1
|
||||
cell := yAxis + 1
|
||||
|
||||
xlsx = checkRow(xlsx)
|
||||
xlsx = completeRow(xlsx, rows, cell)
|
||||
xlsx = completeCol(xlsx, rows, cell)
|
||||
|
||||
xlsx.SheetData.Row[xAxis].C[yAxis].T = "str"
|
||||
xlsx.SheetData.Row[xAxis].C[yAxis].V = value
|
||||
|
||||
output, err := xml.MarshalIndent(xlsx, "", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
saveFileList(file, name, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output))))
|
||||
return file
|
||||
}
|
||||
|
||||
// Completion column element tags of XML in a sheet
|
||||
func completeCol(xlsx xlsxWorksheet, row int, cell int) xlsxWorksheet {
|
||||
if len(xlsx.SheetData.Row) < cell {
|
||||
for i := len(xlsx.SheetData.Row); i < cell; i++ {
|
||||
xlsx.SheetData.Row = append(xlsx.SheetData.Row, xlsxRow{
|
||||
R: i + 1,
|
||||
})
|
||||
}
|
||||
}
|
||||
for k, v := range xlsx.SheetData.Row {
|
||||
if len(v.C) < cell {
|
||||
start := len(v.C)
|
||||
for iii := start; iii < cell; iii++ {
|
||||
xlsx.SheetData.Row[k].C = append(xlsx.SheetData.Row[k].C, xlsxC{
|
||||
R: toAlphaString(iii+1) + strconv.Itoa(k+1),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return xlsx
|
||||
}
|
||||
|
||||
// Completion row element tags of XML in a sheet
|
||||
func completeRow(xlsx xlsxWorksheet, row int, cell int) xlsxWorksheet {
|
||||
if len(xlsx.SheetData.Row) < row {
|
||||
for i := len(xlsx.SheetData.Row); i < row; i++ {
|
||||
xlsx.SheetData.Row = append(xlsx.SheetData.Row, xlsxRow{
|
||||
R: i + 1,
|
||||
})
|
||||
}
|
||||
|
||||
for ii := 0; ii < row; ii++ {
|
||||
start := len(xlsx.SheetData.Row[ii].C)
|
||||
if start == 0 {
|
||||
for iii := start; iii < cell; iii++ {
|
||||
xlsx.SheetData.Row[ii].C = append(xlsx.SheetData.Row[ii].C, xlsxC{
|
||||
R: toAlphaString(iii+1) + strconv.Itoa(ii+1),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return xlsx
|
||||
}
|
||||
|
||||
// Replace xl/worksheets/sheet%d.xml XML tags to self-closing for compatible Office Excel 2007
|
||||
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, `></sheetPr>`, ` />`, -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, `></headerFooter>`, ` />`, -1)
|
||||
workbookMarshal = strings.Replace(workbookMarshal, `></drawing>`, ` />`, -1)
|
||||
return workbookMarshal
|
||||
}
|
||||
|
||||
// Check XML tags and fix discontinuous case, for example:
|
||||
//
|
||||
// <row r="15" spans="1:22" x14ac:dyDescent="0.2">
|
||||
// <c r="A15" s="2" />
|
||||
// <c r="B15" s="2" />
|
||||
// <c r="F15" s="1" />
|
||||
// <c r="G15" s="1" />
|
||||
// </row>
|
||||
//
|
||||
// in this case, we should to change it to
|
||||
//
|
||||
// <row r="15" spans="1:22" x14ac:dyDescent="0.2">
|
||||
// <c r="A15" s="2" />
|
||||
// <c r="B15" s="2" />
|
||||
// <c r="C15" s="2" />
|
||||
// <c r="D15" s="2" />
|
||||
// <c r="E15" s="2" />
|
||||
// <c r="F15" s="1" />
|
||||
// <c r="G15" s="1" />
|
||||
// </row>
|
||||
//
|
||||
func checkRow(xlsx xlsxWorksheet) xlsxWorksheet {
|
||||
for k, v := range xlsx.SheetData.Row {
|
||||
lenCol := len(v.C)
|
||||
endR := getColIndex(v.C[lenCol-1].R)
|
||||
endRow := getRowIndex(v.C[lenCol-1].R)
|
||||
endCol := titleToNumber(endR)
|
||||
if lenCol < endCol {
|
||||
oldRow := xlsx.SheetData.Row[k].C
|
||||
xlsx.SheetData.Row[k].C = xlsx.SheetData.Row[k].C[:0]
|
||||
tmp := []xlsxC{}
|
||||
for i := 0; i <= endCol; i++ {
|
||||
fixAxis := toAlphaString(i+1) + strconv.Itoa(endRow)
|
||||
tmp = append(tmp, xlsxC{
|
||||
R: fixAxis,
|
||||
})
|
||||
}
|
||||
xlsx.SheetData.Row[k].C = tmp
|
||||
for _, y := range oldRow {
|
||||
colAxis := titleToNumber(getColIndex(y.R))
|
||||
xlsx.SheetData.Row[k].C[colAxis] = y
|
||||
}
|
||||
}
|
||||
}
|
||||
return xlsx
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
|
@ -0,0 +1,55 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
func testSetup() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func TestExcelize(t *testing.T) {
|
||||
// Test update a XLSX file
|
||||
file, err := OpenFile("./test/Workbook1.xlsx")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
file = SetCellInt(file, "SHEET2", "B2", 100)
|
||||
file = SetCellStr(file, "SHEET2", "C11", "Knowns")
|
||||
file = NewSheet(file, 3, "TestSheet")
|
||||
file = SetCellInt(file, "Sheet3", "A23", 10)
|
||||
file = SetCellStr(file, "SHEET3", "b230", "10")
|
||||
file = SetActiveSheet(file, 2)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
for i := 1; i <= 300; i++ {
|
||||
file = SetCellStr(file, "SHEET3", fmt.Sprintf("c%d", i), randToken(5))
|
||||
}
|
||||
err = Save(file, "./test/Workbook_2.xlsx")
|
||||
|
||||
// Test create a XLSX file
|
||||
file2 := CreateFile()
|
||||
file2 = NewSheet(file2, 2, "SHEETxxx")
|
||||
file2 = NewSheet(file2, 3, "asd")
|
||||
file2 = SetCellInt(file2, "Sheet2", "A23", 10)
|
||||
file2 = SetCellStr(file2, "SHEET1", "B20", "10")
|
||||
err = Save(file2, "./test/Workbook_3.xlsx")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func randToken(length int) string {
|
||||
b := make([]byte, length)
|
||||
rand.Read(b)
|
||||
return fmt.Sprintf("%x", b)
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Create a new xlsx file
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// xlsx := CreateFile()
|
||||
//
|
||||
func CreateFile() []FileList {
|
||||
var file []FileList
|
||||
file = saveFileList(file, `_rels/.rels`, TEMPLATE_RELS)
|
||||
file = saveFileList(file, `docProps/app.xml`, TEMPLATE_DOCPROPS_APP)
|
||||
file = saveFileList(file, `docProps/core.xml`, TEMPLATE_DOCPROPS_CORE)
|
||||
file = saveFileList(file, `xl/_rels/workbook.xml.rels`, TEMPLATE_WORKBOOK_RELS)
|
||||
file = saveFileList(file, `xl/theme/theme1.xml`, TEMPLATE_THEME)
|
||||
file = saveFileList(file, `xl/worksheets/sheet1.xml`, TEMPLATE_SHEET)
|
||||
file = saveFileList(file, `xl/styles.xml`, TEMPLATE_STYLES)
|
||||
file = saveFileList(file, `xl/workbook.xml`, TEMPLATE_WORKBOOK)
|
||||
file = saveFileList(file, `[Content_Types].xml`, TEMPLATE_CONTENT_TYPES)
|
||||
return file
|
||||
}
|
||||
|
||||
// Save after create or update to an xlsx file at the provided path.
|
||||
func Save(files []FileList, name string) error {
|
||||
buf := new(bytes.Buffer)
|
||||
w := zip.NewWriter(buf)
|
||||
for _, file := range files {
|
||||
f, err := w.Create(file.Key)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err = f.Write([]byte(file.Value))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err := w.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteTo(f)
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ReadZip() takes a pointer to a zip.ReadCloser and returns a
|
||||
// xlsx.File struct populated with its contents. In most cases
|
||||
// ReadZip is not used directly, but is called internally by OpenFile.
|
||||
func ReadZip(f *zip.ReadCloser) ([]FileList, error) {
|
||||
defer f.Close()
|
||||
return ReadZipReader(&f.Reader)
|
||||
}
|
||||
|
||||
// ReadZipReader() can be used to read an XLSX in memory without
|
||||
// touching the filesystem.
|
||||
func ReadZipReader(r *zip.Reader) ([]FileList, error) {
|
||||
var fileList []FileList
|
||||
for _, v := range r.File {
|
||||
singleFile := FileList{
|
||||
Key: v.Name,
|
||||
Value: readFile(v),
|
||||
}
|
||||
fileList = append(fileList, singleFile)
|
||||
}
|
||||
return fileList, nil
|
||||
}
|
||||
|
||||
// Read XML content as string and replace drawing property in XML namespace of sheet
|
||||
func readXml(files []FileList, name string) string {
|
||||
for _, file := range files {
|
||||
if file.Key == name {
|
||||
return strings.Replace(file.Value, "<drawing r:id=", "<drawing rid=", -1)
|
||||
}
|
||||
}
|
||||
return ``
|
||||
}
|
||||
|
||||
// Update given file content in file list of XLSX
|
||||
func saveFileList(files []FileList, name string, content string) []FileList {
|
||||
for k, v := range files {
|
||||
if v.Key == name {
|
||||
files = files[:k+copy(files[k:], files[k+1:])]
|
||||
files = append(files, FileList{
|
||||
Key: name,
|
||||
Value: XMLHeader + content,
|
||||
})
|
||||
return files
|
||||
}
|
||||
}
|
||||
files = append(files, FileList{
|
||||
Key: name,
|
||||
Value: XMLHeader + content,
|
||||
})
|
||||
return files
|
||||
}
|
||||
|
||||
// Read file content as string in a archive file
|
||||
func readFile(file *zip.File) string {
|
||||
rc, err := file.Open()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
buff := bytes.NewBuffer(nil)
|
||||
io.Copy(buff, rc)
|
||||
rc.Close()
|
||||
return string(buff.Bytes())
|
||||
}
|
||||
|
||||
// Convert integer to Excel sheet column title
|
||||
func toAlphaString(value int) string {
|
||||
if value < 0 {
|
||||
return ``
|
||||
}
|
||||
var ans string
|
||||
i := value
|
||||
for i > 0 {
|
||||
ans = string((i-1)%26+65) + ans
|
||||
i = (i - 1) / 26
|
||||
}
|
||||
return ans
|
||||
}
|
||||
|
||||
// Convert Excel sheet column title to int
|
||||
func titleToNumber(s string) int {
|
||||
weight := 0.0
|
||||
sum := 0
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
sum = sum + (int(s[i])-int('A')+1)*int(math.Pow(26, weight))
|
||||
weight++
|
||||
}
|
||||
return sum - 1
|
||||
}
|
||||
|
||||
// Check the file exists
|
||||
func pathExist(_path string) bool {
|
||||
_, err := os.Stat(_path)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Split Excel sheet column title to string and integer, return XAxis
|
||||
func getColIndex(axis string) string {
|
||||
r, err := regexp.Compile(`[^\D]`)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return string(r.ReplaceAll([]byte(axis), []byte("")))
|
||||
}
|
||||
|
||||
// Split Excel sheet column title to string and integer, return YAxis
|
||||
func getRowIndex(axis string) int {
|
||||
r, err := regexp.Compile(`[\D]`)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
row, err := strconv.Atoi(string(r.ReplaceAll([]byte(axis), []byte(""))))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return row
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Create 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.
|
||||
func NewSheet(file []FileList, index int, name string) []FileList {
|
||||
// Update docProps/app.xml
|
||||
file = setAppXml(file)
|
||||
// Update [Content_Types].xml
|
||||
file = setContentTypes(file, index)
|
||||
// Create new sheet /xl/worksheets/sheet%d.xml
|
||||
file = setSheet(file, index)
|
||||
// Update xl/_rels/workbook.xml.rels
|
||||
file = addXlsxWorkbookRels(file, index)
|
||||
// Update xl/workbook.xml
|
||||
file = setWorkbook(file, index, name)
|
||||
return file
|
||||
}
|
||||
|
||||
// Read and update property of contents type of XLSX
|
||||
func setContentTypes(file []FileList, index int) []FileList {
|
||||
var content xlsxTypes
|
||||
xml.Unmarshal([]byte(readXml(file, `[Content_Types].xml`)), &content)
|
||||
content.Overrides = append(content.Overrides, xlsxOverride{
|
||||
PartName: fmt.Sprintf("/xl/worksheets/sheet%d.xml", index),
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
|
||||
})
|
||||
output, err := xml.MarshalIndent(content, "", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
return saveFileList(file, `[Content_Types].xml`, string(output))
|
||||
}
|
||||
|
||||
// Update sheet property by given index
|
||||
func setSheet(file []FileList, index int) []FileList {
|
||||
var xlsx xlsxWorksheet
|
||||
xlsx.Dimension.Ref = "A1"
|
||||
xlsx.SheetViews.SheetView = append(xlsx.SheetViews.SheetView, xlsxSheetView{
|
||||
WorkbookViewId: 0,
|
||||
})
|
||||
output, err := xml.MarshalIndent(xlsx, "", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
path := fmt.Sprintf("xl/worksheets/sheet%d.xml", index)
|
||||
return saveFileList(file, path, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(output))))
|
||||
}
|
||||
|
||||
// Update workbook property of XLSX
|
||||
func setWorkbook(file []FileList, index int, name string) []FileList {
|
||||
var content xlsxWorkbook
|
||||
xml.Unmarshal([]byte(readXml(file, `xl/workbook.xml`)), &content)
|
||||
|
||||
rels := readXlsxWorkbookRels(file)
|
||||
rId := len(rels.Relationships)
|
||||
content.Sheets.Sheet = append(content.Sheets.Sheet, xlsxSheet{
|
||||
Name: name,
|
||||
SheetId: strconv.Itoa(index),
|
||||
Id: "rId" + strconv.Itoa(rId),
|
||||
})
|
||||
output, err := xml.MarshalIndent(content, "", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
return saveFileList(file, `xl/workbook.xml`, replaceRelationshipsNameSpace(string(output)))
|
||||
}
|
||||
|
||||
// Read and unmarshal workbook relationships of XLSX
|
||||
func readXlsxWorkbookRels(file []FileList) xlsxWorkbookRels {
|
||||
var content xlsxWorkbookRels
|
||||
xml.Unmarshal([]byte(readXml(file, `xl/_rels/workbook.xml.rels`)), &content)
|
||||
return content
|
||||
}
|
||||
|
||||
// Update workbook relationships property of XLSX
|
||||
func addXlsxWorkbookRels(file []FileList, sheet int) []FileList {
|
||||
content := readXlsxWorkbookRels(file)
|
||||
rId := len(content.Relationships) + 1
|
||||
content.Relationships = append(content.Relationships, xlsxWorkbookRelation{
|
||||
Id: "rId" + strconv.Itoa(rId),
|
||||
Target: fmt.Sprintf("worksheets/sheet%d.xml", sheet),
|
||||
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
|
||||
})
|
||||
output, err := xml.MarshalIndent(content, "", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
return saveFileList(file, `xl/_rels/workbook.xml.rels`, string(output))
|
||||
}
|
||||
|
||||
// Update docProps/app.xml file of XML
|
||||
func setAppXml(file []FileList) []FileList {
|
||||
return saveFileList(file, `docProps/app.xml`, TEMPLATE_DOCPROPS_APP)
|
||||
}
|
||||
|
||||
// Some tools that read XLSX files have very strict requirements about
|
||||
// the structure of the input XML. In particular both Numbers on the Mac
|
||||
// and SAS dislike inline XML namespace declarations, or namespace
|
||||
// prefixes that don't match the ones that Excel itself uses. This is a
|
||||
// problem because the Go XML library doesn't multiple namespace
|
||||
// declarations in a single element of a document. This function is a
|
||||
// horrible hack to fix that after the XML marshalling is completed.
|
||||
func replaceRelationshipsNameSpace(workbookMarshal string) string {
|
||||
// newWorkbook := strings.Replace(workbookMarshal, `xmlns:relationships="http://schemas.openxmlformats.org/officeDocument/2006/relationships" relationships:id`, `r:id`, -1)
|
||||
// Dirty hack to fix issues #63 and #91; encoding/xml currently
|
||||
// "doesn't allow for additional namespaces to be defined in the
|
||||
// root element of the document," as described by @tealeg in the
|
||||
// comments for #63.
|
||||
oldXmlns := `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`
|
||||
newXmlns := `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">`
|
||||
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)
|
||||
return strings.Replace(rids, `<drawing rid="`, `<drawing r:id="`, -1)
|
||||
}
|
||||
|
||||
// Set default active sheet of XLSX by given index
|
||||
func SetActiveSheet(file []FileList, index int) []FileList {
|
||||
var content xlsxWorkbook
|
||||
if index < 1 {
|
||||
index = 1
|
||||
}
|
||||
index -= 1
|
||||
xml.Unmarshal([]byte(readXml(file, `xl/workbook.xml`)), &content)
|
||||
if len(content.BookViews.WorkBookView) > 0 {
|
||||
content.BookViews.WorkBookView[0].ActiveTab = index
|
||||
} else {
|
||||
content.BookViews.WorkBookView = append(content.BookViews.WorkBookView, xlsxWorkBookView{
|
||||
ActiveTab: index,
|
||||
})
|
||||
}
|
||||
sheets := len(content.Sheets.Sheet)
|
||||
output, err := xml.MarshalIndent(content, "", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
file = saveFileList(file, `xl/workbook.xml`, workBookCompatibility(replaceRelationshipsNameSpace(string(output))))
|
||||
index += 1
|
||||
for i := 0; i < sheets; i++ {
|
||||
xlsx := xlsxWorksheet{}
|
||||
sheetIndex := i + 1
|
||||
path := fmt.Sprintf("xl/worksheets/sheet%d.xml", sheetIndex)
|
||||
xml.Unmarshal([]byte(readXml(file, path)), &xlsx)
|
||||
if index == sheetIndex {
|
||||
if len(xlsx.SheetViews.SheetView) > 0 {
|
||||
xlsx.SheetViews.SheetView[0].TabSelected = true
|
||||
} else {
|
||||
xlsx.SheetViews.SheetView = append(xlsx.SheetViews.SheetView, xlsxSheetView{
|
||||
TabSelected: true,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if len(xlsx.SheetViews.SheetView) > 0 {
|
||||
xlsx.SheetViews.SheetView[0].TabSelected = false
|
||||
}
|
||||
}
|
||||
sheet, err := xml.MarshalIndent(xlsx, "", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
file = saveFileList(file, path, replaceRelationshipsID(replaceWorkSheetsRelationshipsNameSpace(string(sheet))))
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
// 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, `></definedNames>`, ` />`, -1)
|
||||
workbookMarshal = strings.Replace(workbookMarshal, `></calcPr>`, ` />`, -1)
|
||||
workbookMarshal = strings.Replace(workbookMarshal, `></workbookProtection>`, ` />`, -1)
|
||||
workbookMarshal = strings.Replace(workbookMarshal, `></fileRecoveryPr>`, ` />`, -1)
|
||||
return workbookMarshal
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// This file contains default templates for XML files we don't yet
|
||||
// populated based on content.
|
||||
|
||||
package excelize
|
||||
|
||||
const XMLHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
||||
|
||||
const TEMPLATE_DOCPROPS_APP = `<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
|
||||
<TotalTime>0</TotalTime>
|
||||
<Application>Go XLSX</Application>
|
||||
</Properties>`
|
||||
|
||||
const TEMPLATE_CONTENT_TYPES = `<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
||||
<Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
|
||||
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
|
||||
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
|
||||
<Default Extension="xml" ContentType="application/xml"/>
|
||||
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
|
||||
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
|
||||
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
|
||||
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
|
||||
</Types>`
|
||||
|
||||
const TEMPLATE_WORKBOOK = `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><fileVersion appName="xl" lastEdited="4" lowestEdited="4" rupBuild="4505" /><workbookPr filterPrivacy="1" defaultThemeVersion="124226" /><bookViews><workbookView xWindow="240" yWindow="105" windowWidth="14805" windowHeight="8010" /></bookViews><sheets><sheet name="Sheet1" sheetId="1" r:id="rId1" /></sheets><calcPr calcId="122211" fullCalcOnLoad="1" /></workbook>
|
||||
`
|
||||
|
||||
const TEMPLATE_STYLES = `<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="1"><font><sz val="11"/><color theme="1"/><name val="宋体"/><family val="2"/><scheme val="minor"/></font></fonts><fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/></cellXfs><cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles><dxfs count="0"/><tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleMedium9"/></styleSheet>
|
||||
`
|
||||
const TEMPLATE_SHEET = `<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><dimension ref="A1"/><sheetViews><sheetView tabSelected="1" workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="15"/><sheetData/><pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/></worksheet>
|
||||
`
|
||||
|
||||
const TEMPLATE_WORKBOOK_RELS = `<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/></Relationships>`
|
||||
|
||||
const TEMPLATE_DOCPROPS_CORE = `<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:creator>xuri</dc:creator><dcterms:created xsi:type="dcterms:W3CDTF">2006-09-16T00:00:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2006-09-16T00:00:00Z</dcterms:modified></cp:coreProperties>`
|
||||
|
||||
const TEMPLATE_RELS = `<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>`
|
||||
|
||||
const TEMPLATE_THEME = `<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme"><a:themeElements><a:clrScheme name="Office"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F497D"/></a:dk2><a:lt2><a:srgbClr val="EEECE1"/></a:lt2><a:accent1><a:srgbClr val="4F81BD"/></a:accent1><a:accent2><a:srgbClr val="C0504D"/></a:accent2><a:accent3><a:srgbClr val="9BBB59"/></a:accent3><a:accent4><a:srgbClr val="8064A2"/></a:accent4><a:accent5><a:srgbClr val="4BACC6"/></a:accent5><a:accent6><a:srgbClr val="F79646"/></a:accent6><a:hlink><a:srgbClr val="0000FF"/></a:hlink><a:folHlink><a:srgbClr val="800080"/></a:folHlink></a:clrScheme><a:fontScheme name="Office"><a:majorFont><a:latin typeface="Cambria"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS Pゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="宋体"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Times New Roman"/><a:font script="Hebr" typeface="Times New Roman"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="MoolBoran"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Times New Roman"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/>
|
||||
</a:majorFont><a:minorFont><a:latin typeface="Calibri"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS Pゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="宋体"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Arial"/><a:font script="Hebr" typeface="Arial"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="DaunPenh"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Arial"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/>
|
||||
</a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="50000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="35000"><a:schemeClr val="phClr"><a:tint val="37000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="15000"/><a:satMod val="350000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="1"/></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:shade val="51000"/><a:satMod val="130000"/></a:schemeClr></a:gs><a:gs pos="80000"><a:schemeClr val="phClr"><a:shade val="93000"/><a:satMod val="130000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="94000"/><a:satMod val="135000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="0"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w="9525" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"><a:shade val="95000"/><a:satMod val="105000"/></a:schemeClr></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="38100" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="38000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst><a:scene3d><a:camera prst="orthographicFront"><a:rot lat="0" lon="0" rev="0"/></a:camera><a:lightRig rig="threePt" dir="t"><a:rot lat="0" lon="0" rev="1200000"/></a:lightRig></a:scene3d><a:sp3d><a:bevelT w="63500" h="25400"/></a:sp3d></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="40000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="40000"><a:schemeClr val="phClr"><a:tint val="45000"/><a:shade val="99000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="20000"/><a:satMod val="255000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="-80000" r="50000" b="180000"/></a:path></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="80000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="30000"/><a:satMod val="200000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="50000" r="50000" b="50000"/></a:path></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>`
|
Binary file not shown.
|
@ -0,0 +1,49 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
type xlsxTypes struct {
|
||||
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/content-types Types"`
|
||||
Overrides []xlsxOverride `xml:"Override"`
|
||||
Defaults []xlsxDefault `xml:"Default"`
|
||||
}
|
||||
|
||||
type xlsxOverride struct {
|
||||
PartName string `xml:",attr"`
|
||||
ContentType string `xml:",attr"`
|
||||
}
|
||||
|
||||
type xlsxDefault struct {
|
||||
Extension string `xml:",attr"`
|
||||
ContentType string `xml:",attr"`
|
||||
}
|
||||
|
||||
func MakeDefaultContentTypes() (types xlsxTypes) {
|
||||
types.Overrides = make([]xlsxOverride, 8)
|
||||
types.Defaults = make([]xlsxDefault, 2)
|
||||
|
||||
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"
|
||||
types.Overrides[7].PartName = "/xl/theme/theme1.xml"
|
||||
types.Overrides[7].ContentType = "application/vnd.openxmlformats-officedocument.theme+xml"
|
||||
|
||||
types.Defaults[0].Extension = "rels"
|
||||
types.Defaults[0].ContentType = "application/vnd.openxmlformats-package.relationships+xml"
|
||||
types.Defaults[1].Extension = "xml"
|
||||
types.Defaults[1].ContentType = "application/xml"
|
||||
return
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
const (
|
||||
// sheet state values as defined by
|
||||
// http://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.sheetstatevalues.aspx
|
||||
sheetStateVisible = "visible"
|
||||
sheetStateHidden = "hidden"
|
||||
sheetStateVeryHidden = "veryHidden"
|
||||
)
|
||||
|
||||
// xmlxWorkbookRels contains xmlxWorkbookRelations
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// xmlxWorkbookRelation maps sheet id and xl/worksheets/sheet%d.xml
|
||||
type xlsxWorkbookRelation struct {
|
||||
Id string `xml:",attr"`
|
||||
Target string `xml:",attr"`
|
||||
Type string `xml:",attr"`
|
||||
}
|
||||
|
||||
// xlsxWorkbook directly maps the workbook 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.
|
||||
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"`
|
||||
DefinedNames xlsxDefinedNames `xml:"definedNames"`
|
||||
CalcPr xlsxCalcPr `xml:"calcPr"`
|
||||
FileRecoveryPr xlsxFileRecoveryPr `xml:"fileRecoveryPr"`
|
||||
}
|
||||
|
||||
// xlsxFileRecoveryPr maps sheet recovery information
|
||||
type xlsxFileRecoveryPr struct {
|
||||
RepairLoad int `xml:"repairLoad,attr"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
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.
|
||||
type xlsxFileVersion struct {
|
||||
AppName string `xml:"appName,attr,omitempty"`
|
||||
LastEdited string `xml:"lastEdited,attr,omitempty"`
|
||||
LowestEdited string `xml:"lowestEdited,attr,omitempty"`
|
||||
RupBuild string `xml:"rupBuild,attr,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
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"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
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.
|
||||
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"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type xlsxSheets struct {
|
||||
Sheet []xlsxSheet `xml:"sheet"`
|
||||
}
|
||||
|
||||
// xlsxSheet directly maps the sheet 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.
|
||||
type xlsxSheet struct {
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
SheetId string `xml:"sheetId,attr,omitempty"`
|
||||
Id string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
|
||||
State string `xml:"state,attr,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
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
|
||||
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"`
|
||||
Help string `xml:"help,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"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
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"`
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
// xlsxWorksheet directly maps the worksheet 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.
|
||||
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"`
|
||||
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"`
|
||||
}
|
||||
|
||||
// xlsxDrawing change r:id to rid in the namespace
|
||||
type xlsxDrawing struct {
|
||||
RId string `xml:"rid,attr"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type xlsxHeaderFooter struct {
|
||||
DifferentFirst bool `xml:"differentFirst,attr"`
|
||||
DifferentOddEven bool `xml:"differentOddEven,attr"`
|
||||
OddHeader []xlsxOddHeader `xml:"oddHeader"`
|
||||
OddFooter []xlsxOddFooter `xml:"oddFooter"`
|
||||
}
|
||||
|
||||
// xlsxOddHeader directly maps the oddHeader 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.
|
||||
type xlsxOddHeader struct {
|
||||
Content string `xml:",chardata"`
|
||||
}
|
||||
|
||||
// xlsxOddFooter directly maps the oddFooter 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.
|
||||
type xlsxOddFooter struct {
|
||||
Content string `xml:",chardata"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
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"`
|
||||
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"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
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"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type xlsxPageMargins struct {
|
||||
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
|
||||
// http://schemas.openxmlformats.org/spreadsheetml/2006/main -
|
||||
// currently I have not checked it for completeness - it does as much
|
||||
// as I need.
|
||||
type xlsxSheetFormatPr struct {
|
||||
DefaultColWidth float64 `xml:"defaultColWidth,attr,omitempty"`
|
||||
DefaultRowHeight float64 `xml:"defaultRowHeight,attr"`
|
||||
OutlineLevelCol uint8 `xml:"outlineLevelCol,attr,omitempty"`
|
||||
OutlineLevelRow uint8 `xml:"outlineLevelRow,attr,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type xlsxSheetViews struct {
|
||||
SheetView []xlsxSheetView `xml:"sheetView"`
|
||||
}
|
||||
|
||||
// xlsxSheetView directly maps the sheetView 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.
|
||||
type xlsxSheetView struct {
|
||||
// WindowProtection bool `xml:"windowProtection,attr"`
|
||||
// ShowFormulas bool `xml:"showFormulas,attr"`
|
||||
// ShowGridLines bool `xml:"showGridLines,attr"`
|
||||
// ShowRowColHeaders bool `xml:"showRowColHeaders,attr"`
|
||||
// ShowZeros bool `xml:"showZeros,attr"`
|
||||
// RightToLeft bool `xml:"rightToLeft,attr"`
|
||||
TabSelected bool `xml:"tabSelected,attr"`
|
||||
// ShowOutlineSymbols bool `xml:"showOutlineSymbols,attr"`
|
||||
// DefaultGridColor bool `xml:"defaultGridColor,attr"`
|
||||
// View string `xml:"view,attr"`
|
||||
TopLeftCell string `xml:"topLeftCell,attr,omitempty"`
|
||||
// ColorId int `xml:"colorId,attr"`
|
||||
// ZoomScale float64 `xml:"zoomScale,attr"`
|
||||
// ZoomScaleNormal float64 `xml:"zoomScaleNormal,attr"`
|
||||
// ZoomScalePageLayoutView float64 `xml:"zoomScalePageLayoutView,attr"`
|
||||
WorkbookViewId int `xml:"workbookViewId,attr"`
|
||||
Selection []xlsxSelection `xml:"selection"`
|
||||
Pane *xlsxPane `xml:"pane,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.
|
||||
type xlsxSelection struct {
|
||||
Pane string `xml:"pane,attr,omitempty"`
|
||||
ActiveCell string `xml:"activeCell,attr"`
|
||||
ActiveCellId int `xml:"activeCellId,attr"`
|
||||
SQRef string `xml:"sqref,attr"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
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"
|
||||
}
|
||||
|
||||
// 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.
|
||||
type xlsxSheetPr struct {
|
||||
FilterMode bool `xml:"filterMode,attr"`
|
||||
PageSetUpPr []xlsxPageSetUpPr `xml:"pageSetUpPr"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type xlsxPageSetUpPr struct {
|
||||
FitToPage bool `xml:"fitToPage,attr"`
|
||||
}
|
||||
|
||||
// xlsxCols directly maps the cols 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.
|
||||
type xlsxCols struct {
|
||||
Col []xlsxCol `xml:"col"`
|
||||
}
|
||||
|
||||
// xlsxCol directly maps the col 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.
|
||||
type xlsxCol struct {
|
||||
Collapsed bool `xml:"collapsed,attr"`
|
||||
Hidden bool `xml:"hidden,attr"`
|
||||
Max int `xml:"max,attr"`
|
||||
Min int `xml:"min,attr"`
|
||||
Style int `xml:"style,attr"`
|
||||
Width float64 `xml:"width,attr"`
|
||||
CustomWidth int `xml:"customWidth,attr,omitempty"`
|
||||
OutlineLevel uint8 `xml:"outlineLevel,attr,omitempty"`
|
||||
}
|
||||
|
||||
// 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.
|
||||
type xlsxDimension struct {
|
||||
Ref string `xml:"ref,attr"`
|
||||
}
|
||||
|
||||
// xlsxSheetData directly maps the sheetData 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.
|
||||
type xlsxSheetData struct {
|
||||
XMLName xml.Name `xml:"sheetData"`
|
||||
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.
|
||||
type xlsxRow struct {
|
||||
R int `xml:"r,attr"`
|
||||
Spans string `xml:"spans,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"`
|
||||
}
|
||||
|
||||
type xlsxMergeCell struct {
|
||||
Ref string `xml:"ref,attr"` // ref: horiz "A1:C1", vert "B3:B6", both "D3:G4"
|
||||
}
|
||||
|
||||
type xlsxMergeCells struct {
|
||||
XMLName xml.Name //`xml:"mergeCells,omitempty"`
|
||||
Count int `xml:"count,attr,omitempty"`
|
||||
Cells []xlsxMergeCell `xml:"mergeCell,omitempty"`
|
||||
}
|
||||
|
||||
// xlsxC directly maps the c 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.
|
||||
type xlsxC struct {
|
||||
R string `xml:"r,attr"` // Cell ID, e.g. A1
|
||||
S int `xml:"s,attr,omitempty"` // Style reference.
|
||||
// Str string `xml:"str,attr,omitempty"` // Style reference.
|
||||
T string `xml:"t,attr,omitempty"` // Type.
|
||||
F *xlsxF `xml:"f,omitempty"` // Formula
|
||||
V string `xml:"v,omitempty"` // Value
|
||||
}
|
||||
|
||||
// xlsxF directly maps the f 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.
|
||||
type xlsxF struct {
|
||||
Content string `xml:",chardata"`
|
||||
T string `xml:"t,attr,omitempty"` // Formula type
|
||||
Ref string `xml:"ref,attr,omitempty"` // Shared formula ref
|
||||
Si int `xml:"si,attr,omitempty"` // Shared formula index
|
||||
}
|
Loading…
Reference in New Issue