file.go 3.4 KB
Newer Older
xurime's avatar
xurime 已提交
1
// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
xurime's avatar
xurime 已提交
2 3 4 5 6 7
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
// Package excelize providing a set of functions that allow you to write to
// and read from XLSX files. Support reads and writes XLSX file generated by
// Microsoft Excel™ 2007 and later. Support save file without losing original
8
// charts of XLSX. This library needs Go version 1.10 or later.
xurime's avatar
xurime 已提交
9

xurime's avatar
xurime 已提交
10 11 12 13 14
package excelize

import (
	"archive/zip"
	"bytes"
J
Josh Fyne 已提交
15 16
	"fmt"
	"io"
xurime's avatar
xurime 已提交
17 18 19
	"os"
)

xurime's avatar
xurime 已提交
20
// NewFile provides a function to create new file by default template. For
21 22
// example:
//
23
//    xlsx := NewFile()
24
//
25
func NewFile() *File {
26 27 28 29 30 31 32 33 34 35
	file := make(map[string][]byte)
	file["_rels/.rels"] = []byte(XMLHeader + templateRels)
	file["docProps/app.xml"] = []byte(XMLHeader + templateDocpropsApp)
	file["docProps/core.xml"] = []byte(XMLHeader + templateDocpropsCore)
	file["xl/_rels/workbook.xml.rels"] = []byte(XMLHeader + templateWorkbookRels)
	file["xl/theme/theme1.xml"] = []byte(XMLHeader + templateTheme)
	file["xl/worksheets/sheet1.xml"] = []byte(XMLHeader + templateSheet)
	file["xl/styles.xml"] = []byte(XMLHeader + templateStyles)
	file["xl/workbook.xml"] = []byte(XMLHeader + templateWorkbook)
	file["[Content_Types].xml"] = []byte(XMLHeader + templateContentTypes)
36 37
	f := newFile()
	f.SheetCount, f.XLSX = 1, file
38 39
	f.CalcChain = f.calcChainReader()
	f.Comments = make(map[string]*xlsxComments)
40
	f.ContentTypes = f.contentTypesReader()
41
	f.Drawings = make(map[string]*xlsxWsDr)
42
	f.Styles = f.stylesReader()
43 44
	f.DecodeVMLDrawing = make(map[string]*decodeVmlDrawing)
	f.VMLDrawing = make(map[string]*vmlDrawing)
45
	f.WorkBook = f.workbookReader()
xurime's avatar
xurime 已提交
46 47
	f.Relationships = make(map[string]*xlsxRelationships)
	f.Relationships["xl/_rels/workbook.xml.rels"] = f.relsReader("xl/_rels/workbook.xml.rels")
xurime's avatar
xurime 已提交
48
	f.Sheet["xl/worksheets/sheet1.xml"], _ = f.workSheetReader("Sheet1")
49
	f.sheetMap["Sheet1"] = "xl/worksheets/sheet1.xml"
xurime's avatar
xurime 已提交
50
	f.Theme = f.themeReader()
51
	return f
52 53
}

xurime's avatar
xurime 已提交
54
// Save provides a function to override the xlsx file with origin path.
55
func (f *File) Save() error {
J
Josh Fyne 已提交
56
	if f.Path == "" {
xurime's avatar
xurime 已提交
57
		return fmt.Errorf("no path defined for file, consider File.WriteTo or File.Write")
58
	}
59
	return f.SaveAs(f.Path)
xurime's avatar
xurime 已提交
60 61
}

xurime's avatar
xurime 已提交
62 63
// SaveAs provides a function to create or update to an xlsx file at the
// provided path.
64
func (f *File) SaveAs(name string) error {
J
Josh Fyne 已提交
65 66 67 68 69 70 71 72
	file, err := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
	if err != nil {
		return err
	}
	defer file.Close()
	return f.Write(file)
}

xurime's avatar
xurime 已提交
73
// Write provides a function to write to an io.Writer.
J
Josh Fyne 已提交
74
func (f *File) Write(w io.Writer) error {
75 76 77 78 79 80
	_, err := f.WriteTo(w)
	return err
}

// WriteTo implements io.WriterTo to write the file.
func (f *File) WriteTo(w io.Writer) (int64, error) {
81 82 83 84 85 86 87 88 89
	buf, err := f.WriteToBuffer()
	if err != nil {
		return 0, err
	}
	return buf.WriteTo(w)
}

// WriteToBuffer provides a function to get bytes.Buffer from the saved file.
func (f *File) WriteToBuffer() (*bytes.Buffer, error) {
xurime's avatar
xurime 已提交
90
	buf := new(bytes.Buffer)
J
Josh Fyne 已提交
91
	zw := zip.NewWriter(buf)
92 93
	f.calcChainWriter()
	f.commentsWriter()
xurime's avatar
xurime 已提交
94
	f.contentTypesWriter()
95
	f.drawingsWriter()
96
	f.vmlDrawingWriter()
97 98
	f.workBookWriter()
	f.workSheetWriter()
xurime's avatar
xurime 已提交
99
	f.relsWriter()
xurime's avatar
xurime 已提交
100
	f.sharedStringsWriter()
101
	f.styleSheetWriter()
102

103
	for path, content := range f.XLSX {
J
Josh Fyne 已提交
104
		fi, err := zw.Create(path)
xurime's avatar
xurime 已提交
105
		if err != nil {
Z
zaddok 已提交
106
			zw.Close()
107
			return buf, err
xurime's avatar
xurime 已提交
108
		}
109
		_, err = fi.Write(content)
xurime's avatar
xurime 已提交
110
		if err != nil {
Z
zaddok 已提交
111
			zw.Close()
112
			return buf, err
xurime's avatar
xurime 已提交
113 114
		}
	}
115
	return buf, zw.Close()
xurime's avatar
xurime 已提交
116
}