512 lines
23 KiB
Go
512 lines
23 KiB
Go
// Copyright 2016 - 2024 The excelize Authors. All rights reserved. Use of
|
|
// 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 XLAM / XLSM / XLSX / XLTM / XLTX files. Supports reading and
|
|
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
|
|
// Supports complex components by high compatibility, and provided streaming
|
|
// API for generating or reading data from a worksheet with huge amounts of
|
|
// data. This library needs Go version 1.18 or later.
|
|
|
|
package excelize
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestAddComment(t *testing.T) {
|
|
f, err := prepareTestBook1()
|
|
if !assert.NoError(t, err) {
|
|
t.FailNow()
|
|
}
|
|
|
|
s := strings.Repeat("c", TotalCellChars+1)
|
|
assert.NoError(t, f.AddComment("Sheet1", Comment{Cell: "A30", Author: s, Text: s, Paragraph: []RichTextRun{{Text: s}, {Text: s}}}))
|
|
assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "B7", Author: "Excelize", Text: s[:TotalCellChars-1], Paragraph: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment."}}}))
|
|
|
|
// Test add comment on not exists worksheet
|
|
assert.EqualError(t, f.AddComment("SheetN", Comment{Cell: "B7", Author: "Excelize", Paragraph: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment."}}}), "sheet SheetN does not exist")
|
|
// Test add comment on with illegal cell reference
|
|
assert.Equal(t, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")), f.AddComment("Sheet1", Comment{Cell: "A", Author: "Excelize", Paragraph: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment."}}}))
|
|
comments, err := f.GetComments("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, comments, 2)
|
|
comments, err = f.GetComments("Sheet2")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, comments, 1)
|
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddComments.xlsx")))
|
|
|
|
f.Comments["xl/comments2.xml"] = nil
|
|
f.Pkg.Store("xl/comments2.xml", []byte(xml.Header+`<comments xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><authors><author>Excelize: </author></authors><commentList><comment ref="B7" authorId="0"><text><t>Excelize: </t></text></comment></commentList></comments>`))
|
|
comments, err = f.GetComments("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, comments, 2)
|
|
comments, err = f.GetComments("Sheet2")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, comments, 1)
|
|
comments, err = NewFile().GetComments("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, comments, 0)
|
|
|
|
// Test add comments with invalid sheet name
|
|
assert.Equal(t, ErrSheetNameInvalid, f.AddComment("Sheet:1", Comment{Cell: "A1", Author: "Excelize", Text: "This is a comment."}))
|
|
|
|
// Test add comments with unsupported charset
|
|
f.Comments["xl/comments2.xml"] = nil
|
|
f.Pkg.Store("xl/comments2.xml", MacintoshCyrillicCharset)
|
|
_, err = f.GetComments("Sheet2")
|
|
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
|
|
|
// Test add comments with unsupported charset
|
|
f.Comments["xl/comments2.xml"] = nil
|
|
f.Pkg.Store("xl/comments2.xml", MacintoshCyrillicCharset)
|
|
assert.EqualError(t, f.AddComment("Sheet2", Comment{Cell: "A30", Text: "Comment"}), "XML syntax error on line 1: invalid UTF-8")
|
|
|
|
// Test add comments with unsupported charset style sheet
|
|
f.Styles = nil
|
|
f.Pkg.Store(defaultXMLPathStyles, MacintoshCyrillicCharset)
|
|
assert.EqualError(t, f.AddComment("Sheet2", Comment{Cell: "A30", Text: "Comment"}), "XML syntax error on line 1: invalid UTF-8")
|
|
|
|
// Test get comments on not exists worksheet
|
|
comments, err = f.GetComments("SheetN")
|
|
assert.Len(t, comments, 0)
|
|
assert.EqualError(t, err, "sheet SheetN does not exist")
|
|
}
|
|
|
|
func TestDeleteComment(t *testing.T) {
|
|
f, err := prepareTestBook1()
|
|
if !assert.NoError(t, err) {
|
|
t.FailNow()
|
|
}
|
|
|
|
assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "A40", Text: "Excelize: This is a comment1."}))
|
|
assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "A41", Paragraph: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment2."}}}))
|
|
assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "C41", Paragraph: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment3."}}}))
|
|
assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "C41", Paragraph: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment3-1."}}}))
|
|
assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "C42", Paragraph: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment4."}}}))
|
|
assert.NoError(t, f.AddComment("Sheet2", Comment{Cell: "C41", Paragraph: []RichTextRun{{Text: "Excelize: ", Font: &Font{Bold: true}}, {Text: "This is a comment2."}}}))
|
|
|
|
assert.NoError(t, f.DeleteComment("Sheet2", "A40"))
|
|
|
|
comments, err := f.GetComments("Sheet2")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, comments, 5)
|
|
|
|
comments, err = NewFile().GetComments("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, comments, 0)
|
|
|
|
// Test delete comment with invalid sheet name
|
|
assert.Equal(t, ErrSheetNameInvalid, f.DeleteComment("Sheet:1", "A1"))
|
|
// Test delete all comments in a worksheet
|
|
assert.NoError(t, f.DeleteComment("Sheet2", "A41"))
|
|
assert.NoError(t, f.DeleteComment("Sheet2", "C41"))
|
|
assert.NoError(t, f.DeleteComment("Sheet2", "C42"))
|
|
comments, err = f.GetComments("Sheet2")
|
|
assert.NoError(t, err)
|
|
assert.EqualValues(t, 0, len(comments))
|
|
// Test delete comment on not exists worksheet
|
|
assert.EqualError(t, f.DeleteComment("SheetN", "A1"), "sheet SheetN does not exist")
|
|
// Test delete comment with worksheet part
|
|
f.Pkg.Delete("xl/worksheets/sheet1.xml")
|
|
assert.NoError(t, f.DeleteComment("Sheet1", "A22"))
|
|
|
|
f.Comments["xl/comments2.xml"] = nil
|
|
f.Pkg.Store("xl/comments2.xml", MacintoshCyrillicCharset)
|
|
assert.EqualError(t, f.DeleteComment("Sheet2", "A41"), "XML syntax error on line 1: invalid UTF-8")
|
|
|
|
f = NewFile()
|
|
// Test delete comment on a no comments worksheet
|
|
assert.NoError(t, f.DeleteComment("Sheet1", "A1"))
|
|
}
|
|
|
|
func TestDecodeVMLDrawingReader(t *testing.T) {
|
|
f := NewFile()
|
|
path := "xl/drawings/vmlDrawing1.xml"
|
|
f.Pkg.Store(path, MacintoshCyrillicCharset)
|
|
_, err := f.decodeVMLDrawingReader(path)
|
|
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
|
}
|
|
|
|
func TestCommentsReader(t *testing.T) {
|
|
f := NewFile()
|
|
// Test read comments with unsupported charset
|
|
path := "xl/comments1.xml"
|
|
f.Pkg.Store(path, MacintoshCyrillicCharset)
|
|
_, err := f.commentsReader(path)
|
|
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
|
}
|
|
|
|
func TestCountComments(t *testing.T) {
|
|
f := NewFile()
|
|
f.Comments["xl/comments1.xml"] = nil
|
|
assert.Equal(t, f.countComments(), 1)
|
|
}
|
|
|
|
func TestAddDrawingVML(t *testing.T) {
|
|
// Test addDrawingVML with illegal cell reference
|
|
f := NewFile()
|
|
assert.Equal(t, f.addDrawingVML(0, "", &vmlOptions{FormControl: FormControl{Cell: "*"}}), newCellNameToCoordinatesError("*", newInvalidCellNameError("*")))
|
|
|
|
f.Pkg.Store("xl/drawings/vmlDrawing1.vml", MacintoshCyrillicCharset)
|
|
assert.EqualError(t, f.addDrawingVML(0, "xl/drawings/vmlDrawing1.vml", &vmlOptions{sheet: "Sheet1", FormControl: FormControl{Cell: "A1"}}), "XML syntax error on line 1: invalid UTF-8")
|
|
}
|
|
|
|
func TestFormControl(t *testing.T) {
|
|
f := NewFile()
|
|
formControls := []FormControl{
|
|
{
|
|
Cell: "D1", Type: FormControlButton, Macro: "Button1_Click",
|
|
},
|
|
{
|
|
Cell: "A1", Type: FormControlButton, Macro: "Button1_Click",
|
|
Width: 140, Height: 60, Text: "Button 1\n",
|
|
Paragraph: []RichTextRun{
|
|
{
|
|
Font: &Font{
|
|
Bold: true,
|
|
Italic: true,
|
|
Underline: "single",
|
|
Family: "Times New Roman",
|
|
Size: 14,
|
|
Color: "777777",
|
|
},
|
|
Text: "C1=A1+B1",
|
|
},
|
|
},
|
|
Format: GraphicOptions{PrintObject: boolPtr(true), Positioning: "absolute"},
|
|
},
|
|
{
|
|
Cell: "A5", Type: FormControlCheckBox, Text: "Check Box 1",
|
|
Checked: true, Format: GraphicOptions{
|
|
PrintObject: boolPtr(false), Positioning: "oneCell",
|
|
},
|
|
},
|
|
{
|
|
Cell: "A6", Type: FormControlCheckBox, Text: "Check Box 2",
|
|
Format: GraphicOptions{Positioning: "twoCell"},
|
|
},
|
|
{
|
|
Cell: "A7", Type: FormControlOptionButton, Text: "Option Button 1", Checked: true,
|
|
},
|
|
{
|
|
Cell: "A8", Type: FormControlOptionButton, Text: "Option Button 2",
|
|
},
|
|
{
|
|
Cell: "D3", Type: FormControlGroupBox, Text: "Group Box 1",
|
|
Width: 140, Height: 60,
|
|
},
|
|
{
|
|
Cell: "A9", Type: FormControlLabel, Text: "Label 1", Width: 140,
|
|
},
|
|
{
|
|
Cell: "C5", Type: FormControlSpinButton, Width: 40, Height: 60,
|
|
CurrentVal: 7, MinVal: 5, MaxVal: 10, IncChange: 1, CellLink: "C2",
|
|
},
|
|
{
|
|
Cell: "D7", Type: FormControlScrollBar, Width: 140, Height: 20,
|
|
CurrentVal: 50, MinVal: 10, MaxVal: 100, IncChange: 1, PageChange: 1, Horizontally: true, CellLink: "C3",
|
|
},
|
|
{
|
|
Cell: "G1", Type: FormControlScrollBar, Width: 20, Height: 140,
|
|
CurrentVal: 50, MinVal: 1000, MaxVal: 100, IncChange: 1, PageChange: 1, CellLink: "C4",
|
|
},
|
|
}
|
|
for _, formCtrl := range formControls {
|
|
assert.NoError(t, f.AddFormControl("Sheet1", formCtrl))
|
|
}
|
|
// Test get from controls
|
|
result, err := f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, result, 11)
|
|
for i, formCtrl := range formControls {
|
|
assert.Equal(t, formCtrl.Type, result[i].Type)
|
|
assert.Equal(t, formCtrl.Cell, result[i].Cell)
|
|
assert.Equal(t, formCtrl.Macro, result[i].Macro)
|
|
assert.Equal(t, formCtrl.Checked, result[i].Checked)
|
|
assert.Equal(t, formCtrl.CurrentVal, result[i].CurrentVal)
|
|
assert.Equal(t, formCtrl.MinVal, result[i].MinVal)
|
|
assert.Equal(t, formCtrl.MaxVal, result[i].MaxVal)
|
|
assert.Equal(t, formCtrl.IncChange, result[i].IncChange)
|
|
assert.Equal(t, formCtrl.Horizontally, result[i].Horizontally)
|
|
assert.Equal(t, formCtrl.CellLink, result[i].CellLink)
|
|
assert.Equal(t, formCtrl.Text, result[i].Text)
|
|
assert.Equal(t, len(formCtrl.Paragraph), len(result[i].Paragraph))
|
|
}
|
|
assert.NoError(t, f.SetSheetProps("Sheet1", &SheetPropsOptions{CodeName: stringPtr("Sheet1")}))
|
|
file, err := os.ReadFile(filepath.Join("test", "vbaProject.bin"))
|
|
assert.NoError(t, err)
|
|
assert.NoError(t, f.AddVBAProject(file))
|
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddFormControl.xlsm")))
|
|
assert.NoError(t, f.Close())
|
|
f, err = OpenFile(filepath.Join("test", "TestAddFormControl.xlsm"))
|
|
assert.NoError(t, err)
|
|
// Test get from controls before add form controls
|
|
result, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, result, 11)
|
|
// Test add from control to a worksheet which already contains form controls
|
|
assert.NoError(t, f.AddFormControl("Sheet1", FormControl{
|
|
Cell: "D4", Type: FormControlButton, Macro: "Button1_Click",
|
|
Paragraph: []RichTextRun{{Font: &Font{Underline: "double"}, Text: "Button 2"}},
|
|
}))
|
|
// Test get from controls after add form controls
|
|
result, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, result, 12)
|
|
// Test add unsupported form control
|
|
assert.Equal(t, f.AddFormControl("Sheet1", FormControl{
|
|
Cell: "A1", Type: 0x37, Macro: "Button1_Click",
|
|
}), ErrParameterInvalid)
|
|
// Test add form control on not exists worksheet
|
|
assert.Equal(t, ErrSheetNotExist{"SheetN"}, f.AddFormControl("SheetN", FormControl{
|
|
Cell: "A1", Type: FormControlButton, Macro: "Button1_Click",
|
|
}))
|
|
// Test add form control with invalid positioning types
|
|
assert.Equal(t, f.AddFormControl("Sheet1", FormControl{
|
|
Cell: "A1", Type: FormControlButton,
|
|
Format: GraphicOptions{Positioning: "x"},
|
|
}), ErrParameterInvalid)
|
|
// Test add spin form control with illegal cell link reference
|
|
assert.Equal(t, f.AddFormControl("Sheet1", FormControl{
|
|
Cell: "C5", Type: FormControlSpinButton, CellLink: "*",
|
|
}), newCellNameToCoordinatesError("*", newInvalidCellNameError("*")))
|
|
// Test add spin form control with invalid scroll value
|
|
assert.Equal(t, f.AddFormControl("Sheet1", FormControl{
|
|
Cell: "C5", Type: FormControlSpinButton, CurrentVal: MaxFormControlValue + 1,
|
|
}), ErrFormControlValue)
|
|
assert.NoError(t, f.Close())
|
|
// Test delete form control
|
|
f, err = OpenFile(filepath.Join("test", "TestAddFormControl.xlsm"))
|
|
assert.NoError(t, err)
|
|
assert.NoError(t, f.DeleteFormControl("Sheet1", "D1"))
|
|
assert.NoError(t, f.DeleteFormControl("Sheet1", "A1"))
|
|
// Test get from controls after delete form controls
|
|
result, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, result, 9)
|
|
// Test delete form control on not exists worksheet
|
|
assert.Equal(t, ErrSheetNotExist{"SheetN"}, f.DeleteFormControl("SheetN", "A1"))
|
|
// Test delete form control with illegal cell link reference
|
|
assert.Equal(t, f.DeleteFormControl("Sheet1", "A"), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")))
|
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestDeleteFormControl.xlsm")))
|
|
assert.NoError(t, f.Close())
|
|
// Test delete form control with expected element
|
|
f, err = OpenFile(filepath.Join("test", "TestAddFormControl.xlsm"))
|
|
assert.NoError(t, err)
|
|
f.Pkg.Store("xl/drawings/vmlDrawing1.vml", MacintoshCyrillicCharset)
|
|
assert.Error(t, f.DeleteFormControl("Sheet1", "A1"), "XML syntax error on line 1: invalid UTF-8")
|
|
// Test delete form controls with invalid shape anchor
|
|
f.DecodeVMLDrawing["xl/drawings/vmlDrawing1.vml"] = &decodeVmlDrawing{
|
|
Shape: []decodeShape{{Type: "#_x0000_t201", Val: "<x:ClientData ObjectType=\"Scroll\"><x:Anchor>0</x:Anchor></x:ClientData>"}},
|
|
}
|
|
assert.Equal(t, ErrParameterInvalid, f.DeleteFormControl("Sheet1", "A1"))
|
|
assert.NoError(t, f.Close())
|
|
// Test delete form control on a worksheet without form control
|
|
f = NewFile()
|
|
assert.NoError(t, f.DeleteFormControl("Sheet1", "A1"))
|
|
// Test get form controls on a worksheet without form control
|
|
_, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
// Test get form controls on not exists worksheet
|
|
_, err = f.GetFormControls("SheetN")
|
|
assert.Equal(t, ErrSheetNotExist{"SheetN"}, err)
|
|
// Test get form controls with unsupported charset VML drawing
|
|
f, err = OpenFile(filepath.Join("test", "TestAddFormControl.xlsm"))
|
|
assert.NoError(t, err)
|
|
f.Pkg.Store("xl/drawings/vmlDrawing1.vml", MacintoshCyrillicCharset)
|
|
_, err = f.GetFormControls("Sheet1")
|
|
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
|
// Test get form controls with unsupported shape type
|
|
f.DecodeVMLDrawing["xl/drawings/vmlDrawing1.vml"] = &decodeVmlDrawing{
|
|
Shape: []decodeShape{{Type: "_x0000_t202"}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, formControls, 0)
|
|
// Test get form controls with bold font format
|
|
f.DecodeVMLDrawing["xl/drawings/vmlDrawing1.vml"] = &decodeVmlDrawing{
|
|
Shape: []decodeShape{{Type: "#_x0000_t201", Val: "<v:textbox><div><font><b>Text</b></font></div></v:textbox><x:ClientData ObjectType=\"Scroll\"><x:Anchor>0,0,0,0,0,0,0,0</x:Anchor></x:ClientData>"}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.True(t, formControls[0].Paragraph[0].Font.Bold)
|
|
// Test get form controls with italic font format
|
|
f.DecodeVMLDrawing["xl/drawings/vmlDrawing1.vml"] = &decodeVmlDrawing{
|
|
Shape: []decodeShape{{Type: "#_x0000_t201", Val: "<v:textbox><div><font><i>Text</i></font></div></v:textbox><x:ClientData ObjectType=\"Scroll\"><x:Anchor>0,0,0,0,0,0,0,0</x:Anchor></x:ClientData>"}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.True(t, formControls[0].Paragraph[0].Font.Italic)
|
|
// Test get form controls with font format
|
|
f.DecodeVMLDrawing["xl/drawings/vmlDrawing1.vml"] = &decodeVmlDrawing{
|
|
Shape: []decodeShape{{Type: "#_x0000_t201", Val: "<v:textbox><div><font face=\"Calibri\" size=\"280\" color=\"#777777\">Text</font></div></v:textbox><x:ClientData ObjectType=\"Scroll\"><x:Anchor>0,0,0,0,0,0,0,0</x:Anchor></x:ClientData>"}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "Calibri", formControls[0].Paragraph[0].Font.Family)
|
|
assert.Equal(t, 14.0, formControls[0].Paragraph[0].Font.Size)
|
|
assert.Equal(t, "#777777", formControls[0].Paragraph[0].Font.Color)
|
|
// Test get form controls with italic font format
|
|
f.DecodeVMLDrawing["xl/drawings/vmlDrawing1.vml"] = &decodeVmlDrawing{
|
|
Shape: []decodeShape{{Type: "#_x0000_t201", Val: "<v:textbox><div><font><i>Text</i></font></div></v:textbox><x:ClientData ObjectType=\"Scroll\"><x:Anchor>0,0,0,0,0,0,0,0</x:Anchor></x:ClientData>"}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.True(t, formControls[0].Paragraph[0].Font.Italic)
|
|
// Test get form controls with invalid column number
|
|
f.DecodeVMLDrawing["xl/drawings/vmlDrawing1.vml"] = &decodeVmlDrawing{
|
|
Shape: []decodeShape{{Type: "#_x0000_t201", Val: fmt.Sprintf("<x:ClientData ObjectType=\"Scroll\"><x:Anchor>%d,0,0,0,0,0,0,0</x:Anchor></x:ClientData>", MaxColumns)}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.Equal(t, err, ErrColumnNumber)
|
|
assert.Len(t, formControls, 0)
|
|
// Test get form controls with comment (Note) shape type
|
|
f.DecodeVMLDrawing["xl/drawings/vmlDrawing1.vml"] = &decodeVmlDrawing{
|
|
Shape: []decodeShape{{Type: "#_x0000_t201", Val: "<x:ClientData ObjectType=\"Note\"></x:ClientData>"}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, formControls, 0)
|
|
// Test get form controls with unsupported shape type
|
|
f.VMLDrawing["xl/drawings/vmlDrawing1.vml"] = &vmlDrawing{
|
|
Shape: []xlsxShape{{Type: "_x0000_t202"}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, formControls, 0)
|
|
// Test get form controls with invalid column number
|
|
f.VMLDrawing["xl/drawings/vmlDrawing1.vml"] = &vmlDrawing{
|
|
Shape: []xlsxShape{{Type: "#_x0000_t201", Val: fmt.Sprintf("<x:ClientData ObjectType=\"Scroll\"><x:Anchor>%d,0,0,0,0,0,0,0</x:Anchor></x:ClientData>", MaxColumns)}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.Equal(t, err, ErrColumnNumber)
|
|
assert.Len(t, formControls, 0)
|
|
// Test get form controls with invalid shape anchor
|
|
f.VMLDrawing["xl/drawings/vmlDrawing1.vml"] = &vmlDrawing{
|
|
Shape: []xlsxShape{{Type: "#_x0000_t201", Val: "<x:ClientData ObjectType=\"Scroll\"><x:Anchor>x,0,0,0,0,0,0,0</x:Anchor></x:ClientData>"}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.Equal(t, ErrColumnNumber, err)
|
|
assert.Len(t, formControls, 0)
|
|
// Test get form controls with comment (Note) shape type
|
|
f.VMLDrawing["xl/drawings/vmlDrawing1.vml"] = &vmlDrawing{
|
|
Shape: []xlsxShape{{Type: "#_x0000_t201", Val: "<x:ClientData ObjectType=\"Note\"></x:ClientData>"}},
|
|
}
|
|
formControls, err = f.GetFormControls("Sheet1")
|
|
assert.NoError(t, err)
|
|
assert.Len(t, formControls, 0)
|
|
assert.NoError(t, f.Close())
|
|
}
|
|
|
|
func TestExtractFormControl(t *testing.T) {
|
|
// Test extract form control with unsupported charset
|
|
_, err := extractFormControl(string(MacintoshCyrillicCharset))
|
|
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
|
}
|
|
|
|
func TestAddHeaderFooterImage(t *testing.T) {
|
|
f, sheet, wb := NewFile(), "Sheet1", filepath.Join("test", "TestAddHeaderFooterImage.xlsx")
|
|
headerFooterOptions := HeaderFooterOptions{
|
|
DifferentFirst: true,
|
|
OddHeader: "&L&GExcelize&C&G&R&G",
|
|
OddFooter: "&L&GExcelize&C&G&R&G",
|
|
FirstHeader: "&L&GExcelize&C&G&R&G",
|
|
FirstFooter: "&L&GExcelize&C&G&R&G",
|
|
}
|
|
assert.NoError(t, f.SetHeaderFooter(sheet, &headerFooterOptions))
|
|
assert.NoError(t, f.SetSheetView(sheet, -1, &ViewOptions{View: stringPtr("pageLayout")}))
|
|
images := map[string][]byte{
|
|
".wmf": nil, ".tif": nil, ".png": nil,
|
|
".jpg": nil, ".gif": nil, ".emz": nil, ".emf": nil,
|
|
}
|
|
for ext := range images {
|
|
img, err := os.ReadFile(filepath.Join("test", "images", "excel"+ext))
|
|
assert.NoError(t, err)
|
|
images[ext] = img
|
|
}
|
|
for _, opt := range []struct {
|
|
position HeaderFooterImagePositionType
|
|
file []byte
|
|
isFooter bool
|
|
firstPage bool
|
|
ext string
|
|
}{
|
|
{position: HeaderFooterImagePositionLeft, file: images[".tif"], firstPage: true, ext: ".tif"},
|
|
{position: HeaderFooterImagePositionCenter, file: images[".gif"], firstPage: true, ext: ".gif"},
|
|
{position: HeaderFooterImagePositionRight, file: images[".png"], firstPage: true, ext: ".png"},
|
|
{position: HeaderFooterImagePositionLeft, file: images[".emf"], isFooter: true, firstPage: true, ext: ".emf"},
|
|
{position: HeaderFooterImagePositionCenter, file: images[".wmf"], isFooter: true, firstPage: true, ext: ".wmf"},
|
|
{position: HeaderFooterImagePositionRight, file: images[".emz"], isFooter: true, firstPage: true, ext: ".emz"},
|
|
{position: HeaderFooterImagePositionLeft, file: images[".png"], ext: ".png"},
|
|
{position: HeaderFooterImagePositionCenter, file: images[".png"], ext: ".png"},
|
|
{position: HeaderFooterImagePositionRight, file: images[".png"], ext: ".png"},
|
|
{position: HeaderFooterImagePositionLeft, file: images[".tif"], isFooter: true, ext: ".tif"},
|
|
{position: HeaderFooterImagePositionCenter, file: images[".tif"], isFooter: true, ext: ".tif"},
|
|
{position: HeaderFooterImagePositionRight, file: images[".tif"], isFooter: true, ext: ".tif"},
|
|
} {
|
|
assert.NoError(t, f.AddHeaderFooterImage(sheet, &HeaderFooterImageOptions{
|
|
Position: opt.position,
|
|
File: opt.file,
|
|
IsFooter: opt.isFooter,
|
|
FirstPage: opt.firstPage,
|
|
Extension: opt.ext,
|
|
Width: "50pt",
|
|
Height: "32pt",
|
|
}))
|
|
}
|
|
assert.NoError(t, f.SetCellValue(sheet, "A1", "Example"))
|
|
|
|
// Test add header footer image with not exist sheet
|
|
assert.EqualError(t, f.AddHeaderFooterImage("SheetN", nil), "sheet SheetN does not exist")
|
|
// Test add header footer image with unsupported file type
|
|
assert.Equal(t, f.AddHeaderFooterImage(sheet, &HeaderFooterImageOptions{
|
|
Extension: "jpg",
|
|
}), ErrImgExt)
|
|
assert.NoError(t, f.SaveAs(wb))
|
|
assert.NoError(t, f.Close())
|
|
// Test change already exist header image with the different image
|
|
f, err := OpenFile(wb)
|
|
assert.NoError(t, err)
|
|
assert.NoError(t, f.AddHeaderFooterImage(sheet, &HeaderFooterImageOptions{
|
|
File: images[".jpg"],
|
|
FirstPage: true,
|
|
Extension: ".jpg",
|
|
Width: "50pt",
|
|
Height: "32pt",
|
|
}))
|
|
assert.NoError(t, f.Save())
|
|
assert.NoError(t, f.Close())
|
|
|
|
// Test add header image with unsupported charset VML drawing
|
|
f, err = OpenFile(wb)
|
|
assert.NoError(t, err)
|
|
f.Pkg.Store("xl/drawings/vmlDrawing1.vml", MacintoshCyrillicCharset)
|
|
assert.EqualError(t, f.AddHeaderFooterImage(sheet, &HeaderFooterImageOptions{
|
|
File: images[".jpg"],
|
|
Extension: ".jpg",
|
|
Width: "50pt",
|
|
Height: "32pt",
|
|
}), "XML syntax error on line 1: invalid UTF-8")
|
|
assert.NoError(t, f.Close())
|
|
// Test set legacy drawing header/footer with unsupported charset content types
|
|
f = NewFile()
|
|
f.ContentTypes = nil
|
|
f.Pkg.Store(defaultXMLPathContentTypes, MacintoshCyrillicCharset)
|
|
assert.EqualError(t, f.AddHeaderFooterImage(sheet, &HeaderFooterImageOptions{
|
|
Extension: ".png",
|
|
File: images[".png"],
|
|
Width: "50pt",
|
|
Height: "32pt",
|
|
}), "XML syntax error on line 1: invalid UTF-8")
|
|
assert.NoError(t, f.Close())
|
|
}
|