forked from p30928647/excelize
This closes #744, the `Save`, `Write` and `WriteTo` function accept saving options
This commit is contained in:
parent
0c5cdfec18
commit
fb1aab7add
|
@ -48,6 +48,8 @@ func TestEncrypt(t *testing.T) {
|
||||||
cell, err = f.GetCellValue("Sheet1", "A1")
|
cell, err = f.GetCellValue("Sheet1", "A1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, "SECRET", cell)
|
assert.Equal(t, "SECRET", cell)
|
||||||
|
// Test remove password by save workbook with options
|
||||||
|
assert.NoError(t, f.Save(Options{Password: ""}))
|
||||||
assert.NoError(t, f.Close())
|
assert.NoError(t, f.Close())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,13 +136,13 @@ func newFile() *File {
|
||||||
|
|
||||||
// OpenReader read data stream from io.Reader and return a populated
|
// OpenReader read data stream from io.Reader and return a populated
|
||||||
// spreadsheet file.
|
// spreadsheet file.
|
||||||
func OpenReader(r io.Reader, opt ...Options) (*File, error) {
|
func OpenReader(r io.Reader, opts ...Options) (*File, error) {
|
||||||
b, err := ioutil.ReadAll(r)
|
b, err := ioutil.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
f := newFile()
|
f := newFile()
|
||||||
f.options = parseOptions(opt...)
|
f.options = parseOptions(opts...)
|
||||||
if f.options.UnzipSizeLimit == 0 {
|
if f.options.UnzipSizeLimit == 0 {
|
||||||
f.options.UnzipSizeLimit = UnzipSizeLimit
|
f.options.UnzipSizeLimit = UnzipSizeLimit
|
||||||
if f.options.UnzipXMLSizeLimit > f.options.UnzipSizeLimit {
|
if f.options.UnzipXMLSizeLimit > f.options.UnzipSizeLimit {
|
||||||
|
|
|
@ -186,18 +186,15 @@ func TestOpenFile(t *testing.T) {
|
||||||
|
|
||||||
func TestSaveFile(t *testing.T) {
|
func TestSaveFile(t *testing.T) {
|
||||||
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
||||||
if !assert.NoError(t, err) {
|
assert.NoError(t, err)
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
assert.EqualError(t, f.SaveAs(filepath.Join("test", "TestSaveFile.xlsb")), ErrWorkbookFileFormat.Error())
|
assert.EqualError(t, f.SaveAs(filepath.Join("test", "TestSaveFile.xlsb")), ErrWorkbookFileFormat.Error())
|
||||||
for _, ext := range []string{".xlam", ".xlsm", ".xlsx", ".xltm", ".xltx"} {
|
for _, ext := range []string{".xlam", ".xlsm", ".xlsx", ".xltm", ".xltx"} {
|
||||||
assert.NoError(t, f.SaveAs(filepath.Join("test", fmt.Sprintf("TestSaveFile%s", ext))))
|
assert.NoError(t, f.SaveAs(filepath.Join("test", fmt.Sprintf("TestSaveFile%s", ext))))
|
||||||
}
|
}
|
||||||
assert.NoError(t, f.Close())
|
assert.NoError(t, f.Close())
|
||||||
|
|
||||||
f, err = OpenFile(filepath.Join("test", "TestSaveFile.xlsx"))
|
f, err = OpenFile(filepath.Join("test", "TestSaveFile.xlsx"))
|
||||||
if !assert.NoError(t, err) {
|
assert.NoError(t, err)
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
assert.NoError(t, f.Save())
|
assert.NoError(t, f.Save())
|
||||||
assert.NoError(t, f.Close())
|
assert.NoError(t, f.Close())
|
||||||
}
|
}
|
||||||
|
|
42
file.go
42
file.go
|
@ -55,44 +55,32 @@ func NewFile() *File {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save provides a function to override the spreadsheet with origin path.
|
// Save provides a function to override the spreadsheet with origin path.
|
||||||
func (f *File) Save() error {
|
func (f *File) Save(opts ...Options) error {
|
||||||
if f.Path == "" {
|
if f.Path == "" {
|
||||||
return ErrSave
|
return ErrSave
|
||||||
}
|
}
|
||||||
if f.options != nil {
|
for i := range opts {
|
||||||
return f.SaveAs(f.Path, *f.options)
|
f.options = &opts[i]
|
||||||
}
|
}
|
||||||
return f.SaveAs(f.Path)
|
return f.SaveAs(f.Path, *f.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveAs provides a function to create or update to a spreadsheet at the
|
// SaveAs provides a function to create or update to a spreadsheet at the
|
||||||
// provided path.
|
// provided path.
|
||||||
func (f *File) SaveAs(name string, opt ...Options) error {
|
func (f *File) SaveAs(name string, opts ...Options) error {
|
||||||
if len(name) > MaxFilePathLength {
|
if len(name) > MaxFilePathLength {
|
||||||
return ErrMaxFilePathLength
|
return ErrMaxFilePathLength
|
||||||
}
|
}
|
||||||
f.Path = name
|
f.Path = name
|
||||||
contentType, ok := map[string]string{
|
if _, ok := supportedContentType[filepath.Ext(f.Path)]; !ok {
|
||||||
".xlam": ContentTypeAddinMacro,
|
|
||||||
".xlsm": ContentTypeMacro,
|
|
||||||
".xlsx": ContentTypeSheetML,
|
|
||||||
".xltm": ContentTypeTemplateMacro,
|
|
||||||
".xltx": ContentTypeTemplate,
|
|
||||||
}[filepath.Ext(f.Path)]
|
|
||||||
if !ok {
|
|
||||||
return ErrWorkbookFileFormat
|
return ErrWorkbookFileFormat
|
||||||
}
|
}
|
||||||
f.setContentTypePartProjectExtensions(contentType)
|
|
||||||
file, err := os.OpenFile(filepath.Clean(name), os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)
|
file, err := os.OpenFile(filepath.Clean(name), os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
f.options = nil
|
return f.Write(file, opts...)
|
||||||
for i := range opt {
|
|
||||||
f.options = &opt[i]
|
|
||||||
}
|
|
||||||
return f.Write(file)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes and cleanup the open temporary file for the spreadsheet.
|
// Close closes and cleanup the open temporary file for the spreadsheet.
|
||||||
|
@ -113,13 +101,23 @@ func (f *File) Close() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write provides a function to write to an io.Writer.
|
// Write provides a function to write to an io.Writer.
|
||||||
func (f *File) Write(w io.Writer) error {
|
func (f *File) Write(w io.Writer, opts ...Options) error {
|
||||||
_, err := f.WriteTo(w)
|
_, err := f.WriteTo(w, opts...)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteTo implements io.WriterTo to write the file.
|
// WriteTo implements io.WriterTo to write the file.
|
||||||
func (f *File) WriteTo(w io.Writer) (int64, error) {
|
func (f *File) WriteTo(w io.Writer, opts ...Options) (int64, error) {
|
||||||
|
for i := range opts {
|
||||||
|
f.options = &opts[i]
|
||||||
|
}
|
||||||
|
if len(f.Path) != 0 {
|
||||||
|
contentType, ok := supportedContentType[filepath.Ext(f.Path)]
|
||||||
|
if !ok {
|
||||||
|
return 0, ErrWorkbookFileFormat
|
||||||
|
}
|
||||||
|
f.setContentTypePartProjectExtensions(contentType)
|
||||||
|
}
|
||||||
if f.options != nil && f.options.Password != "" {
|
if f.options != nil && f.options.Password != "" {
|
||||||
buf, err := f.WriteToBuffer()
|
buf, err := f.WriteToBuffer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -71,6 +71,14 @@ func TestWriteTo(t *testing.T) {
|
||||||
_, err := f.WriteTo(bufio.NewWriter(&buf))
|
_, err := f.WriteTo(bufio.NewWriter(&buf))
|
||||||
assert.EqualError(t, err, "zip: FileHeader.Name too long")
|
assert.EqualError(t, err, "zip: FileHeader.Name too long")
|
||||||
}
|
}
|
||||||
|
// Test write with unsupported workbook file format
|
||||||
|
{
|
||||||
|
f, buf := File{Pkg: sync.Map{}}, bytes.Buffer{}
|
||||||
|
f.Pkg.Store("/d", []byte("s"))
|
||||||
|
f.Path = "Book1.xls"
|
||||||
|
_, err := f.WriteTo(bufio.NewWriter(&buf))
|
||||||
|
assert.EqualError(t, err, ErrWorkbookFileFormat.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClose(t *testing.T) {
|
func TestClose(t *testing.T) {
|
||||||
|
|
|
@ -144,6 +144,15 @@ const (
|
||||||
// supportedImageTypes defined supported image types.
|
// supportedImageTypes defined supported image types.
|
||||||
var supportedImageTypes = map[string]string{".gif": ".gif", ".jpg": ".jpeg", ".jpeg": ".jpeg", ".png": ".png", ".tif": ".tiff", ".tiff": ".tiff", ".emf": ".emf", ".wmf": ".wmf", ".emz": ".emz", ".wmz": ".wmz"}
|
var supportedImageTypes = map[string]string{".gif": ".gif", ".jpg": ".jpeg", ".jpeg": ".jpeg", ".png": ".png", ".tif": ".tiff", ".tiff": ".tiff", ".emf": ".emf", ".wmf": ".wmf", ".emz": ".emz", ".wmz": ".wmz"}
|
||||||
|
|
||||||
|
// supportedContentType defined supported file format types.
|
||||||
|
var supportedContentType = map[string]string{
|
||||||
|
".xlam": ContentTypeAddinMacro,
|
||||||
|
".xlsm": ContentTypeMacro,
|
||||||
|
".xlsx": ContentTypeSheetML,
|
||||||
|
".xltm": ContentTypeTemplateMacro,
|
||||||
|
".xltx": ContentTypeTemplate,
|
||||||
|
}
|
||||||
|
|
||||||
// xlsxCNvPr directly maps the cNvPr (Non-Visual Drawing Properties). This
|
// xlsxCNvPr directly maps the cNvPr (Non-Visual Drawing Properties). This
|
||||||
// element specifies non-visual canvas properties. This allows for additional
|
// element specifies non-visual canvas properties. This allows for additional
|
||||||
// information that does not affect the appearance of the picture to be stored.
|
// information that does not affect the appearance of the picture to be stored.
|
||||||
|
|
Loading…
Reference in New Issue