commit
						a9d3ee2869
					
				| @ -0,0 +1,79 @@ | ||||
| * 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 | ||||
| } | ||||
| 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 | ||||
| } | ||||
											
												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
	
	 Ri Xu
						Ri Xu