forked from p30928647/excelize
Resolve #369,#370
add error return value exported functions: GetMergeCells ProtectSheet UnprotectSheet UpdateLinkedValue GetMergeCells SetSheetVisible inner functions: workSheetReader copySheet
This commit is contained in:
parent
c423617e9d
commit
f2df344739
10
adjust.go
10
adjust.go
|
@ -31,18 +31,20 @@ const (
|
|||
// adjustDataValidations, adjustProtectedCells
|
||||
//
|
||||
func (f *File) adjustHelper(sheet string, dir adjustDirection, num, offset int) error {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dir == rows {
|
||||
f.adjustRowDimensions(xlsx, num, offset)
|
||||
} else {
|
||||
f.adjustColDimensions(xlsx, num, offset)
|
||||
}
|
||||
f.adjustHyperlinks(xlsx, sheet, dir, num, offset)
|
||||
if err := f.adjustMergeCells(xlsx, dir, num, offset); err != nil {
|
||||
if err = f.adjustMergeCells(xlsx, dir, num, offset); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.adjustAutoFilter(xlsx, dir, num, offset); err != nil {
|
||||
if err = f.adjustAutoFilter(xlsx, dir, num, offset); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ func TestAdjustAutoFilter(t *testing.T) {
|
|||
|
||||
func TestAdjustHelper(t *testing.T) {
|
||||
f := NewFile()
|
||||
f.NewSheet("Sheet2")
|
||||
f.Sheet["xl/worksheets/sheet1.xml"] = &xlsxWorksheet{
|
||||
MergeCells: &xlsxMergeCells{
|
||||
Cells: []*xlsxMergeCell{
|
||||
|
@ -61,6 +62,6 @@ func TestAdjustHelper(t *testing.T) {
|
|||
},
|
||||
}
|
||||
// testing adjustHelper with illegal cell coordinates.
|
||||
assert.EqualError(t, f.adjustHelper("sheet1", rows, 0, 0), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||
assert.EqualError(t, f.adjustHelper("sheet2", rows, 0, 0), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
|
||||
assert.EqualError(t, f.adjustHelper("Sheet1", rows, 0, 0), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||
assert.EqualError(t, f.adjustHelper("Sheet2", rows, 0, 0), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
|
||||
}
|
||||
|
|
102
cell.go
102
cell.go
|
@ -69,63 +69,67 @@ func (f *File) GetCellValue(sheet, axis string) (string, error) {
|
|||
// Note that default date format is m/d/yy h:mm of time.Time type value. You can
|
||||
// set numbers format by SetCellStyle() method.
|
||||
func (f *File) SetCellValue(sheet, axis string, value interface{}) error {
|
||||
var err error
|
||||
switch v := value.(type) {
|
||||
case int:
|
||||
f.SetCellInt(sheet, axis, v)
|
||||
err = f.SetCellInt(sheet, axis, v)
|
||||
case int8:
|
||||
f.SetCellInt(sheet, axis, int(v))
|
||||
err = f.SetCellInt(sheet, axis, int(v))
|
||||
case int16:
|
||||
f.SetCellInt(sheet, axis, int(v))
|
||||
err = f.SetCellInt(sheet, axis, int(v))
|
||||
case int32:
|
||||
f.SetCellInt(sheet, axis, int(v))
|
||||
err = f.SetCellInt(sheet, axis, int(v))
|
||||
case int64:
|
||||
f.SetCellInt(sheet, axis, int(v))
|
||||
err = f.SetCellInt(sheet, axis, int(v))
|
||||
case uint:
|
||||
f.SetCellInt(sheet, axis, int(v))
|
||||
err = f.SetCellInt(sheet, axis, int(v))
|
||||
case uint8:
|
||||
f.SetCellInt(sheet, axis, int(v))
|
||||
err = f.SetCellInt(sheet, axis, int(v))
|
||||
case uint16:
|
||||
f.SetCellInt(sheet, axis, int(v))
|
||||
err = f.SetCellInt(sheet, axis, int(v))
|
||||
case uint32:
|
||||
f.SetCellInt(sheet, axis, int(v))
|
||||
err = f.SetCellInt(sheet, axis, int(v))
|
||||
case uint64:
|
||||
f.SetCellInt(sheet, axis, int(v))
|
||||
err = f.SetCellInt(sheet, axis, int(v))
|
||||
case float32:
|
||||
f.SetCellFloat(sheet, axis, float64(v), -1, 32)
|
||||
err = f.SetCellFloat(sheet, axis, float64(v), -1, 32)
|
||||
case float64:
|
||||
f.SetCellFloat(sheet, axis, v, -1, 64)
|
||||
err = f.SetCellFloat(sheet, axis, v, -1, 64)
|
||||
case string:
|
||||
f.SetCellStr(sheet, axis, v)
|
||||
err = f.SetCellStr(sheet, axis, v)
|
||||
case []byte:
|
||||
f.SetCellStr(sheet, axis, string(v))
|
||||
err = f.SetCellStr(sheet, axis, string(v))
|
||||
case time.Duration:
|
||||
f.SetCellDefault(sheet, axis, strconv.FormatFloat(v.Seconds()/86400.0, 'f', -1, 32))
|
||||
f.setDefaultTimeStyle(sheet, axis, 21)
|
||||
err = f.SetCellDefault(sheet, axis, strconv.FormatFloat(v.Seconds()/86400.0, 'f', -1, 32))
|
||||
err = f.setDefaultTimeStyle(sheet, axis, 21)
|
||||
case time.Time:
|
||||
excelTime, err := timeToExcelTime(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if excelTime > 0 {
|
||||
f.SetCellDefault(sheet, axis, strconv.FormatFloat(excelTime, 'f', -1, 64))
|
||||
f.setDefaultTimeStyle(sheet, axis, 22)
|
||||
err = f.SetCellDefault(sheet, axis, strconv.FormatFloat(excelTime, 'f', -1, 64))
|
||||
err = f.setDefaultTimeStyle(sheet, axis, 22)
|
||||
} else {
|
||||
f.SetCellStr(sheet, axis, v.Format(time.RFC3339Nano))
|
||||
err = f.SetCellStr(sheet, axis, v.Format(time.RFC3339Nano))
|
||||
}
|
||||
case bool:
|
||||
f.SetCellBool(sheet, axis, v)
|
||||
err = f.SetCellBool(sheet, axis, v)
|
||||
case nil:
|
||||
f.SetCellStr(sheet, axis, "")
|
||||
err = f.SetCellStr(sheet, axis, "")
|
||||
default:
|
||||
f.SetCellStr(sheet, axis, fmt.Sprintf("%v", value))
|
||||
err = f.SetCellStr(sheet, axis, fmt.Sprintf("%v", value))
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// SetCellInt provides a function to set int type value of a cell by given
|
||||
// worksheet name, cell coordinates and cell value.
|
||||
func (f *File) SetCellInt(sheet, axis string, value int) error {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -139,7 +143,10 @@ func (f *File) SetCellInt(sheet, axis string, value int) error {
|
|||
// SetCellBool provides a function to set bool type value of a cell by given
|
||||
// worksheet name, cell name and cell value.
|
||||
func (f *File) SetCellBool(sheet, axis string, value bool) error {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -164,7 +171,10 @@ func (f *File) SetCellBool(sheet, axis string, value bool) error {
|
|||
// f.SetCellFloat("Sheet1", "A1", float64(x), 2, 32)
|
||||
//
|
||||
func (f *File) SetCellFloat(sheet, axis string, value float64, prec, bitSize int) error {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -178,7 +188,10 @@ func (f *File) SetCellFloat(sheet, axis string, value float64, prec, bitSize int
|
|||
// SetCellStr provides a function to set string type value of a cell. Total
|
||||
// number of characters that a cell can contain 32767 characters.
|
||||
func (f *File) SetCellStr(sheet, axis, value string) error {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -203,7 +216,10 @@ func (f *File) SetCellStr(sheet, axis, value string) error {
|
|||
// SetCellDefault provides a function to set string type value of a cell as
|
||||
// default format without escaping the cell.
|
||||
func (f *File) SetCellDefault(sheet, axis, value string) error {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -231,7 +247,10 @@ func (f *File) GetCellFormula(sheet, axis string) (string, error) {
|
|||
// SetCellFormula provides a function to set cell formula by given string and
|
||||
// worksheet name.
|
||||
func (f *File) SetCellFormula(sheet, axis, formula string) error {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cellData, _, _, err := f.prepareCell(xlsx, sheet, axis)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -264,8 +283,11 @@ func (f *File) GetCellHyperLink(sheet, axis string) (bool, string, error) {
|
|||
return false, "", err
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
axis, err := f.mergeCellsParser(xlsx, axis)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
axis, err = f.mergeCellsParser(xlsx, axis)
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
|
@ -302,8 +324,11 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
axis, err := f.mergeCellsParser(xlsx, axis)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
axis, err = f.mergeCellsParser(xlsx, axis)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -367,7 +392,10 @@ func (f *File) MergeCell(sheet, hcell, vcell string) error {
|
|||
hcell, _ = CoordinatesToCellName(hcol, hrow)
|
||||
vcell, _ = CoordinatesToCellName(vcol, vrow)
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if xlsx.MergeCells != nil {
|
||||
ref := hcell + ":" + vcell
|
||||
cells := make([]*xlsxMergeCell, 0, len(xlsx.MergeCells.Cells))
|
||||
|
@ -446,8 +474,10 @@ func (f *File) prepareCell(xlsx *xlsxWorksheet, sheet, cell string) (*xlsxC, int
|
|||
// getCellStringFunc does common value extraction workflow for all GetCell*
|
||||
// methods. Passed function implements specific part of required logic.
|
||||
func (f *File) getCellStringFunc(sheet, axis string, fn func(x *xlsxWorksheet, c *xlsxC) (string, bool, error)) (string, error) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
var err error
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
axis, err = f.mergeCellsParser(xlsx, axis)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
5
chart.go
5
chart.go
|
@ -449,7 +449,10 @@ func (f *File) AddChart(sheet, cell, format string) error {
|
|||
return err
|
||||
}
|
||||
// Read sheet data.
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Add first picture for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder.
|
||||
drawingID := f.countDrawings() + 1
|
||||
chartID := f.countCharts() + 1
|
||||
|
|
37
col.go
37
col.go
|
@ -31,7 +31,10 @@ func (f *File) GetColVisible(sheet, col string) (bool, error) {
|
|||
return visible, err
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if xlsx.Cols == nil {
|
||||
return visible, err
|
||||
}
|
||||
|
@ -61,7 +64,10 @@ func (f *File) SetColVisible(sheet, col string, visible bool) error {
|
|||
Hidden: !visible,
|
||||
CustomWidth: true,
|
||||
}
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if xlsx.Cols == nil {
|
||||
cols := xlsxCols{}
|
||||
cols.Col = append(cols.Col, colData)
|
||||
|
@ -93,7 +99,10 @@ func (f *File) GetColOutlineLevel(sheet, col string) (uint8, error) {
|
|||
if err != nil {
|
||||
return level, err
|
||||
}
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if xlsx.Cols == nil {
|
||||
return level, err
|
||||
}
|
||||
|
@ -123,7 +132,10 @@ func (f *File) SetColOutlineLevel(sheet, col string, level uint8) error {
|
|||
OutlineLevel: level,
|
||||
CustomWidth: true,
|
||||
}
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if xlsx.Cols == nil {
|
||||
cols := xlsxCols{}
|
||||
cols.Col = append(cols.Col, colData)
|
||||
|
@ -162,7 +174,10 @@ func (f *File) SetColWidth(sheet, startcol, endcol string, width float64) error
|
|||
min, max = max, min
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
col := xlsxCol{
|
||||
Min: min,
|
||||
Max: max,
|
||||
|
@ -288,7 +303,7 @@ func (f *File) positionObjectPixels(sheet string, col, row, x1, y1, width, heigh
|
|||
// getColWidth provides a function to get column width in pixels by given
|
||||
// sheet name and column index.
|
||||
func (f *File) getColWidth(sheet string, col int) int {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, _ := f.workSheetReader(sheet)
|
||||
if xlsx.Cols != nil {
|
||||
var width float64
|
||||
for _, v := range xlsx.Cols.Col {
|
||||
|
@ -311,7 +326,10 @@ func (f *File) GetColWidth(sheet, col string) (float64, error) {
|
|||
if err != nil {
|
||||
return defaultColWidthPixels, err
|
||||
}
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return defaultColWidthPixels, err
|
||||
}
|
||||
if xlsx.Cols != nil {
|
||||
var width float64
|
||||
for _, v := range xlsx.Cols.Col {
|
||||
|
@ -355,7 +373,10 @@ func (f *File) RemoveCol(sheet, col string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for rowIdx := range xlsx.SheetData.Row {
|
||||
rowData := &xlsx.SheetData.Row[rowIdx]
|
||||
for colIdx := range rowData.C {
|
||||
|
|
|
@ -80,7 +80,10 @@ func (f *File) AddComment(sheet, cell, format string) error {
|
|||
return err
|
||||
}
|
||||
// Read sheet data.
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
commentID := f.countComments() + 1
|
||||
drawingVML := "xl/drawings/vmlDrawing" + strconv.Itoa(commentID) + ".vml"
|
||||
sheetRelationshipsComments := "../comments" + strconv.Itoa(commentID) + ".xml"
|
||||
|
|
|
@ -208,7 +208,7 @@ func convDataValidationOperatior(o DataValidationOperator) string {
|
|||
// dvRange.Sqref = "A1:B2"
|
||||
// dvRange.SetRange(10, 20, excelize.DataValidationTypeWhole, excelize.DataValidationOperatorBetween)
|
||||
// dvRange.SetError(excelize.DataValidationErrorStyleStop, "error title", "error body")
|
||||
// xlsx.AddDataValidation("Sheet1", dvRange)
|
||||
// err := xlsx.AddDataValidation("Sheet1", dvRange)
|
||||
//
|
||||
// Example 2, set data validation on Sheet1!A3:B4 with validation criteria
|
||||
// settings, and show input message when cell is selected:
|
||||
|
@ -217,7 +217,7 @@ func convDataValidationOperatior(o DataValidationOperator) string {
|
|||
// dvRange.Sqref = "A3:B4"
|
||||
// dvRange.SetRange(10, 20, excelize.DataValidationTypeWhole, excelize.DataValidationOperatorGreaterThan)
|
||||
// dvRange.SetInput("input title", "input body")
|
||||
// xlsx.AddDataValidation("Sheet1", dvRange)
|
||||
// err = xlsx.AddDataValidation("Sheet1", dvRange)
|
||||
//
|
||||
// Example 3, set data validation on Sheet1!A5:B6 with validation criteria
|
||||
// settings, create in-cell dropdown by allowing list source:
|
||||
|
@ -225,13 +225,17 @@ func convDataValidationOperatior(o DataValidationOperator) string {
|
|||
// dvRange = excelize.NewDataValidation(true)
|
||||
// dvRange.Sqref = "A5:B6"
|
||||
// dvRange.SetDropList([]string{"1", "2", "3"})
|
||||
// xlsx.AddDataValidation("Sheet1", dvRange)
|
||||
// err = xlsx.AddDataValidation("Sheet1", dvRange)
|
||||
//
|
||||
func (f *File) AddDataValidation(sheet string, dv *DataValidation) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
func (f *File) AddDataValidation(sheet string, dv *DataValidation) error {
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if nil == xlsx.DataValidations {
|
||||
xlsx.DataValidations = new(xlsxDataValidations)
|
||||
}
|
||||
xlsx.DataValidations.DataValidation = append(xlsx.DataValidations.DataValidation, dv)
|
||||
xlsx.DataValidations.Count = len(xlsx.DataValidations.DataValidation)
|
||||
return err
|
||||
}
|
||||
|
|
26
excelize.go
26
excelize.go
|
@ -14,6 +14,7 @@ import (
|
|||
"archive/zip"
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -112,10 +113,10 @@ func (f *File) setDefaultTimeStyle(sheet, axis string, format int) error {
|
|||
|
||||
// workSheetReader provides a function to get the pointer to the structure
|
||||
// after deserialization by given worksheet name.
|
||||
func (f *File) workSheetReader(sheet string) *xlsxWorksheet {
|
||||
func (f *File) workSheetReader(sheet string) (*xlsxWorksheet, error) {
|
||||
name, ok := f.sheetMap[trimSheetName(sheet)]
|
||||
if !ok {
|
||||
name = "xl/worksheets/" + strings.ToLower(sheet) + ".xml"
|
||||
return nil, fmt.Errorf("Sheet %s is not exist", sheet)
|
||||
}
|
||||
if f.Sheet[name] == nil {
|
||||
var xlsx xlsxWorksheet
|
||||
|
@ -131,7 +132,7 @@ func (f *File) workSheetReader(sheet string) *xlsxWorksheet {
|
|||
}
|
||||
f.Sheet[name] = &xlsx
|
||||
}
|
||||
return f.Sheet[name]
|
||||
return f.Sheet[name], nil
|
||||
}
|
||||
|
||||
// checkSheet provides a function to fill each row element and make that is
|
||||
|
@ -197,9 +198,12 @@ func replaceWorkSheetsRelationshipsNameSpaceBytes(workbookMarshal []byte) []byte
|
|||
// </c>
|
||||
// </row>
|
||||
//
|
||||
func (f *File) UpdateLinkedValue() {
|
||||
func (f *File) UpdateLinkedValue() error {
|
||||
for _, name := range f.GetSheetMap() {
|
||||
xlsx := f.workSheetReader(name)
|
||||
xlsx, err := f.workSheetReader(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for indexR := range xlsx.SheetData.Row {
|
||||
for indexC, col := range xlsx.SheetData.Row[indexR].C {
|
||||
if col.F != nil && col.V != "" {
|
||||
|
@ -209,14 +213,16 @@ func (f *File) UpdateLinkedValue() {
|
|||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMergeCells provides a function to get all merged cells from a worksheet currently.
|
||||
func (f *File) GetMergeCells(sheet string) []MergeCell {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
|
||||
func (f *File) GetMergeCells(sheet string) ([]MergeCell, error) {
|
||||
var mergeCells []MergeCell
|
||||
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return mergeCells, err
|
||||
}
|
||||
if xlsx.MergeCells != nil {
|
||||
mergeCells = make([]MergeCell, 0, len(xlsx.MergeCells.Cells))
|
||||
|
||||
|
@ -228,7 +234,7 @@ func (f *File) GetMergeCells(sheet string) []MergeCell {
|
|||
}
|
||||
}
|
||||
|
||||
return mergeCells
|
||||
return mergeCells, err
|
||||
}
|
||||
|
||||
// MergeCell define a merged cell data.
|
||||
|
|
|
@ -57,10 +57,10 @@ func TestOpenFile(t *testing.T) {
|
|||
xlsx.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.")
|
||||
xlsx.SetCellInt("Sheet3", "A23", 10)
|
||||
xlsx.SetCellStr("Sheet3", "b230", "10")
|
||||
xlsx.SetCellStr("Sheet10", "b230", "10")
|
||||
assert.EqualError(t, xlsx.SetCellStr("Sheet10", "b230", "10"), "Sheet Sheet10 is not exist")
|
||||
|
||||
// Test set cell string value with illegal row number.
|
||||
assert.EqualError(t, xlsx.SetCellStr("Sheet10", "A", "10"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||
assert.EqualError(t, xlsx.SetCellStr("Sheet1", "A", "10"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||
|
||||
xlsx.SetActiveSheet(2)
|
||||
// Test get cell formula with given rows number.
|
||||
|
@ -298,7 +298,7 @@ func TestGetCellHyperLink(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
t.Log(link, target)
|
||||
link, target, err = xlsx.GetCellHyperLink("Sheet3", "H3")
|
||||
assert.NoError(t, err)
|
||||
assert.EqualError(t, err, "Sheet Sheet3 is not exist")
|
||||
t.Log(link, target)
|
||||
}
|
||||
|
||||
|
@ -417,7 +417,7 @@ func TestGetMergeCells(t *testing.T) {
|
|||
}
|
||||
sheet1 := xlsx.GetSheetName(1)
|
||||
|
||||
mergeCells := xlsx.GetMergeCells(sheet1)
|
||||
mergeCells, err := xlsx.GetMergeCells(sheet1)
|
||||
if !assert.Len(t, mergeCells, len(wants)) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
@ -784,7 +784,8 @@ func TestColumnVisibility(t *testing.T) {
|
|||
assert.EqualError(t, err, `invalid column name "*"`)
|
||||
assert.EqualError(t, xlsx.SetColVisible("Sheet1", "*", false), `invalid column name "*"`)
|
||||
|
||||
assert.NoError(t, xlsx.SetColVisible("Sheet3", "E", false))
|
||||
err = xlsx.SetColVisible("Sheet3", "E", false)
|
||||
assert.EqualError(t, err, "Sheet Sheet3 is not exist")
|
||||
assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestColumnVisibility.xlsx")))
|
||||
})
|
||||
|
||||
|
@ -804,10 +805,7 @@ func TestCopySheet(t *testing.T) {
|
|||
}
|
||||
|
||||
idx := xlsx.NewSheet("CopySheet")
|
||||
err = xlsx.CopySheet(1, idx)
|
||||
if !assert.NoError(t, err) {
|
||||
t.FailNow()
|
||||
}
|
||||
assert.EqualError(t, xlsx.CopySheet(1, idx), "Sheet sheet1 is not exist")
|
||||
|
||||
xlsx.SetCellValue("Sheet4", "F1", "Hello")
|
||||
val, err := xlsx.GetCellValue("Sheet1", "F1")
|
||||
|
@ -923,9 +921,8 @@ func TestAutoFilter(t *testing.T) {
|
|||
for i, format := range formats {
|
||||
t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
|
||||
err = xlsx.AutoFilter("Sheet3", "D4", "B1", format)
|
||||
if assert.NoError(t, err) {
|
||||
assert.EqualError(t, err, "Sheet Sheet3 is not exist")
|
||||
assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, i+1)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
2
file.go
2
file.go
|
@ -50,7 +50,7 @@ func NewFile() *File {
|
|||
f.WorkBook = f.workbookReader()
|
||||
f.WorkBookRels = f.workbookRelsReader()
|
||||
f.WorkSheetRels = make(map[string]*xlsxWorkbookRels)
|
||||
f.Sheet["xl/worksheets/sheet1.xml"] = f.workSheetReader("Sheet1")
|
||||
f.Sheet["xl/worksheets/sheet1.xml"], _ = f.workSheetReader("Sheet1")
|
||||
f.sheetMap["Sheet1"] = "xl/worksheets/sheet1.xml"
|
||||
f.Theme = f.themeReader()
|
||||
return f
|
||||
|
|
17
picture.go
17
picture.go
|
@ -132,7 +132,6 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
|
|||
// }
|
||||
//
|
||||
func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string, file []byte) error {
|
||||
var err error
|
||||
var drawingHyperlinkRID int
|
||||
var hyperlinkType string
|
||||
ext, ok := supportImageTypes[extension]
|
||||
|
@ -148,7 +147,10 @@ func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string,
|
|||
return err
|
||||
}
|
||||
// Read sheet data.
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Add first picture for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder.
|
||||
drawingID := f.countDrawings() + 1
|
||||
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
|
||||
|
@ -225,7 +227,7 @@ func (f *File) deleteSheetRelationships(sheet, rID string) {
|
|||
// addSheetLegacyDrawing provides a function to add legacy drawing element to
|
||||
// xl/worksheets/sheet%d.xml by given worksheet name and relationship index.
|
||||
func (f *File) addSheetLegacyDrawing(sheet string, rID int) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, _ := f.workSheetReader(sheet)
|
||||
xlsx.LegacyDrawing = &xlsxLegacyDrawing{
|
||||
RID: "rId" + strconv.Itoa(rID),
|
||||
}
|
||||
|
@ -234,7 +236,7 @@ func (f *File) addSheetLegacyDrawing(sheet string, rID int) {
|
|||
// addSheetDrawing provides a function to add drawing element to
|
||||
// xl/worksheets/sheet%d.xml by given worksheet name and relationship index.
|
||||
func (f *File) addSheetDrawing(sheet string, rID int) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, _ := f.workSheetReader(sheet)
|
||||
xlsx.Drawing = &xlsxDrawing{
|
||||
RID: "rId" + strconv.Itoa(rID),
|
||||
}
|
||||
|
@ -243,7 +245,7 @@ func (f *File) addSheetDrawing(sheet string, rID int) {
|
|||
// addSheetPicture provides a function to add picture element to
|
||||
// xl/worksheets/sheet%d.xml by given worksheet name and relationship index.
|
||||
func (f *File) addSheetPicture(sheet string, rID int) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, _ := f.workSheetReader(sheet)
|
||||
xlsx.Picture = &xlsxPicture{
|
||||
RID: "rId" + strconv.Itoa(rID),
|
||||
}
|
||||
|
@ -500,7 +502,10 @@ func (f *File) GetPicture(sheet, cell string) (string, []byte, error) {
|
|||
}
|
||||
col--
|
||||
row--
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return "", []byte{}, err
|
||||
}
|
||||
if xlsx.Drawing == nil {
|
||||
return "", []byte{}, err
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ func TestGetPicture(t *testing.T) {
|
|||
|
||||
// Try to get picture from a worksheet that doesn't contain any images.
|
||||
file, raw, err = xlsx.GetPicture("Sheet3", "I9")
|
||||
assert.NoError(t, err)
|
||||
assert.EqualError(t, err, "Sheet Sheet3 is not exist")
|
||||
assert.Empty(t, file)
|
||||
assert.Empty(t, raw)
|
||||
|
||||
|
|
52
rows.go
52
rows.go
|
@ -35,7 +35,10 @@ func (f *File) GetRows(sheet string) ([][]string, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if xlsx != nil {
|
||||
output, _ := xml.Marshal(f.Sheet[name])
|
||||
f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpaceBytes(output))
|
||||
|
@ -165,7 +168,10 @@ func (err ErrSheetNotExist) Error() string {
|
|||
// }
|
||||
//
|
||||
func (f *File) Rows(sheet string) (*Rows, error) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name, ok := f.sheetMap[trimSheetName(sheet)]
|
||||
if !ok {
|
||||
return nil, ErrSheetNotExist{sheet}
|
||||
|
@ -225,7 +231,10 @@ func (f *File) SetRowHeight(sheet string, row int, height float64) error {
|
|||
return newInvalidRowNumberError(row)
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
prepareSheetXML(xlsx, 0, row)
|
||||
|
||||
|
@ -238,7 +247,7 @@ func (f *File) SetRowHeight(sheet string, row int, height float64) error {
|
|||
// getRowHeight provides a function to get row height in pixels by given sheet
|
||||
// name and row index.
|
||||
func (f *File) getRowHeight(sheet string, row int) int {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, _ := f.workSheetReader(sheet)
|
||||
for _, v := range xlsx.SheetData.Row {
|
||||
if v.R == row+1 && v.Ht != 0 {
|
||||
return int(convertRowHeightToPixels(v.Ht))
|
||||
|
@ -258,7 +267,10 @@ func (f *File) GetRowHeight(sheet string, row int) (float64, error) {
|
|||
return defaultRowHeightPixels, newInvalidRowNumberError(row)
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return defaultRowHeightPixels, err
|
||||
}
|
||||
if row > len(xlsx.SheetData.Row) {
|
||||
return defaultRowHeightPixels, nil // it will be better to use 0, but we take care with BC
|
||||
}
|
||||
|
@ -321,7 +333,10 @@ func (f *File) SetRowVisible(sheet string, row int, visible bool) error {
|
|||
return newInvalidRowNumberError(row)
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prepareSheetXML(xlsx, 0, row)
|
||||
xlsx.SheetData.Row[row-1].Hidden = !visible
|
||||
return nil
|
||||
|
@ -338,7 +353,10 @@ func (f *File) GetRowVisible(sheet string, row int) (bool, error) {
|
|||
return false, newInvalidRowNumberError(row)
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if row > len(xlsx.SheetData.Row) {
|
||||
return false, nil
|
||||
}
|
||||
|
@ -355,7 +373,10 @@ func (f *File) SetRowOutlineLevel(sheet string, row int, level uint8) error {
|
|||
if row < 1 {
|
||||
return newInvalidRowNumberError(row)
|
||||
}
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prepareSheetXML(xlsx, 0, row)
|
||||
xlsx.SheetData.Row[row-1].OutlineLevel = level
|
||||
return nil
|
||||
|
@ -371,7 +392,10 @@ func (f *File) GetRowOutlineLevel(sheet string, row int) (uint8, error) {
|
|||
if row < 1 {
|
||||
return 0, newInvalidRowNumberError(row)
|
||||
}
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if row > len(xlsx.SheetData.Row) {
|
||||
return 0, nil
|
||||
}
|
||||
|
@ -392,7 +416,10 @@ func (f *File) RemoveRow(sheet string, row int) error {
|
|||
return newInvalidRowNumberError(row)
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if row > len(xlsx.SheetData.Row) {
|
||||
return nil
|
||||
}
|
||||
|
@ -445,7 +472,10 @@ func (f *File) DuplicateRowTo(sheet string, row, row2 int) error {
|
|||
return newInvalidRowNumberError(row)
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if row > len(xlsx.SheetData.Row) || row2 < 1 || row == row2 {
|
||||
return nil
|
||||
}
|
||||
|
|
17
rows_test.go
17
rows_test.go
|
@ -96,8 +96,8 @@ func TestRowVisibility(t *testing.T) {
|
|||
t.FailNow()
|
||||
}
|
||||
|
||||
assert.NoError(t, xlsx.SetRowVisible("Sheet3", 2, false))
|
||||
assert.NoError(t, xlsx.SetRowVisible("Sheet3", 2, true))
|
||||
assert.EqualError(t, xlsx.SetRowVisible("Sheet3", 2, false), "Sheet Sheet3 is not exist")
|
||||
assert.EqualError(t, xlsx.SetRowVisible("Sheet3", 2, true), "Sheet Sheet3 is not exist")
|
||||
xlsx.GetRowVisible("Sheet3", 2)
|
||||
xlsx.GetRowVisible("Sheet3", 25)
|
||||
assert.EqualError(t, xlsx.SetRowVisible("Sheet3", 0, true), "invalid row number 0")
|
||||
|
@ -112,8 +112,8 @@ func TestRowVisibility(t *testing.T) {
|
|||
func TestRemoveRow(t *testing.T) {
|
||||
xlsx := NewFile()
|
||||
sheet1 := xlsx.GetSheetName(1)
|
||||
r := xlsx.workSheetReader(sheet1)
|
||||
|
||||
r, err := xlsx.workSheetReader(sheet1)
|
||||
assert.NoError(t, err)
|
||||
const (
|
||||
colCount = 10
|
||||
rowCount = 10
|
||||
|
@ -143,7 +143,7 @@ func TestRemoveRow(t *testing.T) {
|
|||
t.FailNow()
|
||||
}
|
||||
|
||||
err := xlsx.AutoFilter(sheet1, "A2", "A2", `{"column":"A","expression":"x != blanks"}`)
|
||||
err = xlsx.AutoFilter(sheet1, "A2", "A2", `{"column":"A","expression":"x != blanks"}`)
|
||||
if !assert.NoError(t, err) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
@ -170,8 +170,8 @@ func TestRemoveRow(t *testing.T) {
|
|||
func TestInsertRow(t *testing.T) {
|
||||
xlsx := NewFile()
|
||||
sheet1 := xlsx.GetSheetName(1)
|
||||
r := xlsx.workSheetReader(sheet1)
|
||||
|
||||
r, err := xlsx.workSheetReader(sheet1)
|
||||
assert.NoError(t, err)
|
||||
const (
|
||||
colCount = 10
|
||||
rowCount = 10
|
||||
|
@ -202,7 +202,8 @@ func TestInsertRow(t *testing.T) {
|
|||
func TestInsertRowInEmptyFile(t *testing.T) {
|
||||
xlsx := NewFile()
|
||||
sheet1 := xlsx.GetSheetName(1)
|
||||
r := xlsx.workSheetReader(sheet1)
|
||||
r, err := xlsx.workSheetReader(sheet1)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, xlsx.InsertRow(sheet1, 1))
|
||||
assert.Len(t, r.SheetData.Row, 0)
|
||||
assert.NoError(t, xlsx.InsertRow(sheet1, 2))
|
||||
|
|
5
shape.go
5
shape.go
|
@ -259,7 +259,10 @@ func (f *File) AddShape(sheet, cell, format string) error {
|
|||
return err
|
||||
}
|
||||
// Read sheet data.
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Add first shape for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder.
|
||||
drawingID := f.countDrawings() + 1
|
||||
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
|
||||
|
|
82
sheet.go
82
sheet.go
|
@ -245,7 +245,7 @@ func (f *File) SetActiveSheet(index int) {
|
|||
}
|
||||
}
|
||||
for idx, name := range f.GetSheetMap() {
|
||||
xlsx := f.workSheetReader(name)
|
||||
xlsx, _ := f.workSheetReader(name)
|
||||
if len(xlsx.SheetViews.SheetView) > 0 {
|
||||
xlsx.SheetViews.SheetView[0].TabSelected = false
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ func (f *File) SetActiveSheet(index int) {
|
|||
// XLSX. If not found the active sheet will be return integer 0.
|
||||
func (f *File) GetActiveSheetIndex() int {
|
||||
for idx, name := range f.GetSheetMap() {
|
||||
xlsx := f.workSheetReader(name)
|
||||
xlsx, _ := f.workSheetReader(name)
|
||||
for _, sheetView := range xlsx.SheetViews.SheetView {
|
||||
if sheetView.TabSelected {
|
||||
return idx
|
||||
|
@ -380,11 +380,10 @@ func (f *File) SetSheetBackground(sheet, picture string) error {
|
|||
if !ok {
|
||||
return errors.New("unsupported image extension")
|
||||
}
|
||||
pictureID := f.countMedia() + 1
|
||||
rID := f.addSheetRelationships(sheet, SourceRelationshipImage, "../media/image"+strconv.Itoa(pictureID)+ext, "")
|
||||
f.addSheetPicture(sheet, rID)
|
||||
file, _ := ioutil.ReadFile(picture)
|
||||
f.addMedia(file, ext)
|
||||
name := f.addMedia(file, ext)
|
||||
rID := f.addSheetRelationships(sheet, SourceRelationshipImage, strings.Replace(name, "xl", "..", 1), "")
|
||||
f.addSheetPicture(sheet, rID)
|
||||
f.setContentTypePartImageExtensions()
|
||||
return err
|
||||
}
|
||||
|
@ -452,14 +451,16 @@ func (f *File) CopySheet(from, to int) error {
|
|||
if from < 1 || to < 1 || from == to || f.GetSheetName(from) == "" || f.GetSheetName(to) == "" {
|
||||
return errors.New("invalid worksheet index")
|
||||
}
|
||||
f.copySheet(from, to)
|
||||
return nil
|
||||
return f.copySheet(from, to)
|
||||
}
|
||||
|
||||
// copySheet provides a function to duplicate a worksheet by gave source and
|
||||
// target worksheet name.
|
||||
func (f *File) copySheet(from, to int) {
|
||||
sheet := f.workSheetReader("sheet" + strconv.Itoa(from))
|
||||
func (f *File) copySheet(from, to int) error {
|
||||
sheet, err := f.workSheetReader("sheet" + strconv.Itoa(from))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
worksheet := deepcopy.Copy(sheet).(*xlsxWorksheet)
|
||||
path := "xl/worksheets/sheet" + strconv.Itoa(to) + ".xml"
|
||||
if len(worksheet.SheetViews.SheetView) > 0 {
|
||||
|
@ -475,6 +476,7 @@ func (f *File) copySheet(from, to int) {
|
|||
if ok {
|
||||
f.XLSX[toRels] = f.XLSX[fromRels]
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// SetSheetVisible provides a function to set worksheet visible by given worksheet
|
||||
|
@ -488,9 +490,9 @@ func (f *File) copySheet(from, to int) {
|
|||
//
|
||||
// For example, hide Sheet1:
|
||||
//
|
||||
// xlsx.SetSheetVisible("Sheet1", false)
|
||||
// err := xlsx.SetSheetVisible("Sheet1", false)
|
||||
//
|
||||
func (f *File) SetSheetVisible(name string, visible bool) {
|
||||
func (f *File) SetSheetVisible(name string, visible bool) error {
|
||||
name = trimSheetName(name)
|
||||
content := f.workbookReader()
|
||||
if visible {
|
||||
|
@ -499,7 +501,7 @@ func (f *File) SetSheetVisible(name string, visible bool) {
|
|||
content.Sheets.Sheet[k].State = ""
|
||||
}
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
count := 0
|
||||
for _, v := range content.Sheets.Sheet {
|
||||
|
@ -508,7 +510,10 @@ func (f *File) SetSheetVisible(name string, visible bool) {
|
|||
}
|
||||
}
|
||||
for k, v := range content.Sheets.Sheet {
|
||||
xlsx := f.workSheetReader(f.GetSheetMap()[k])
|
||||
xlsx, err := f.workSheetReader(f.GetSheetMap()[k])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tabSelected := false
|
||||
if len(xlsx.SheetViews.SheetView) > 0 {
|
||||
tabSelected = xlsx.SheetViews.SheetView[0].TabSelected
|
||||
|
@ -517,6 +522,7 @@ func (f *File) SetSheetVisible(name string, visible bool) {
|
|||
content.Sheets.Sheet[k].State = "hidden"
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseFormatPanesSet provides a function to parse the panes settings.
|
||||
|
@ -611,9 +617,12 @@ func parseFormatPanesSet(formatSet string) (*formatPanes, error) {
|
|||
//
|
||||
// xlsx.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
|
||||
//
|
||||
func (f *File) SetPanes(sheet, panes string) {
|
||||
func (f *File) SetPanes(sheet, panes string) error {
|
||||
fs, _ := parseFormatPanesSet(panes)
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p := &xlsxPane{
|
||||
ActivePane: fs.ActivePane,
|
||||
TopLeftCell: fs.TopLeftCell,
|
||||
|
@ -638,6 +647,7 @@ func (f *File) SetPanes(sheet, panes string) {
|
|||
})
|
||||
}
|
||||
xlsx.SheetViews.SheetView[len(xlsx.SheetViews.SheetView)-1].Selection = s
|
||||
return err
|
||||
}
|
||||
|
||||
// GetSheetVisible provides a function to get worksheet visible by given worksheet
|
||||
|
@ -678,10 +688,16 @@ func (f *File) SearchSheet(sheet, value string, reg ...bool) ([]string, error) {
|
|||
for _, r := range reg {
|
||||
regSearch = r
|
||||
}
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
|
||||
var (
|
||||
result []string
|
||||
)
|
||||
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
name, ok := f.sheetMap[trimSheetName(sheet)]
|
||||
if !ok {
|
||||
return result, nil
|
||||
|
@ -740,13 +756,16 @@ func (f *File) SearchSheet(sheet, value string, reg ...bool) ([]string, error) {
|
|||
// or deliberately changing, moving, or deleting data in a worksheet. For
|
||||
// example, protect Sheet1 with protection settings:
|
||||
//
|
||||
// xlsx.ProtectSheet("Sheet1", &excelize.FormatSheetProtection{
|
||||
// err := xlsx.ProtectSheet("Sheet1", &excelize.FormatSheetProtection{
|
||||
// Password: "password",
|
||||
// EditScenarios: false,
|
||||
// })
|
||||
//
|
||||
func (f *File) ProtectSheet(sheet string, settings *FormatSheetProtection) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
func (f *File) ProtectSheet(sheet string, settings *FormatSheetProtection) error {
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if settings == nil {
|
||||
settings = &FormatSheetProtection{
|
||||
EditObjects: true,
|
||||
|
@ -775,12 +794,17 @@ func (f *File) ProtectSheet(sheet string, settings *FormatSheetProtection) {
|
|||
if settings.Password != "" {
|
||||
xlsx.SheetProtection.Password = genSheetPasswd(settings.Password)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UnprotectSheet provides a function to unprotect an Excel worksheet.
|
||||
func (f *File) UnprotectSheet(sheet string) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
func (f *File) UnprotectSheet(sheet string) error {
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
xlsx.SheetProtection = nil
|
||||
return err
|
||||
}
|
||||
|
||||
// trimSheetName provides a function to trim invaild characters by given worksheet
|
||||
|
@ -989,7 +1013,10 @@ func (p *PageLayoutPaperSize) getPageLayout(ps *xlsxPageSetUp) {
|
|||
// 118 | PRC Envelope #10 Rotated (458 mm x 324 mm)
|
||||
//
|
||||
func (f *File) SetPageLayout(sheet string, opts ...PageLayoutOption) error {
|
||||
s := f.workSheetReader(sheet)
|
||||
s, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ps := s.PageSetUp
|
||||
if ps == nil {
|
||||
ps = new(xlsxPageSetUp)
|
||||
|
@ -999,7 +1026,7 @@ func (f *File) SetPageLayout(sheet string, opts ...PageLayoutOption) error {
|
|||
for _, opt := range opts {
|
||||
opt.setPageLayout(ps)
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// GetPageLayout provides a function to gets worksheet page layout.
|
||||
|
@ -1008,13 +1035,16 @@ func (f *File) SetPageLayout(sheet string, opts ...PageLayoutOption) error {
|
|||
// PageLayoutOrientation(string)
|
||||
// PageLayoutPaperSize(int)
|
||||
func (f *File) GetPageLayout(sheet string, opts ...PageLayoutOptionPtr) error {
|
||||
s := f.workSheetReader(sheet)
|
||||
s, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ps := s.PageSetUp
|
||||
|
||||
for _, opt := range opts {
|
||||
opt.getPageLayout(ps)
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// workSheetRelsReader provides a function to get the pointer to the structure
|
||||
|
|
14
sheetpr.go
14
sheetpr.go
|
@ -154,7 +154,10 @@ func (o *AutoPageBreaks) getSheetPrOption(pr *xlsxSheetPr) {
|
|||
// AutoPageBreaks(bool)
|
||||
// OutlineSummaryBelow(bool)
|
||||
func (f *File) SetSheetPrOptions(name string, opts ...SheetPrOption) error {
|
||||
sheet := f.workSheetReader(name)
|
||||
sheet, err := f.workSheetReader(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pr := sheet.SheetPr
|
||||
if pr == nil {
|
||||
pr = new(xlsxSheetPr)
|
||||
|
@ -164,7 +167,7 @@ func (f *File) SetSheetPrOptions(name string, opts ...SheetPrOption) error {
|
|||
for _, opt := range opts {
|
||||
opt.setSheetPrOption(pr)
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// GetSheetPrOptions provides a function to gets worksheet properties.
|
||||
|
@ -177,11 +180,14 @@ func (f *File) SetSheetPrOptions(name string, opts ...SheetPrOption) error {
|
|||
// AutoPageBreaks(bool)
|
||||
// OutlineSummaryBelow(bool)
|
||||
func (f *File) GetSheetPrOptions(name string, opts ...SheetPrOptionPtr) error {
|
||||
sheet := f.workSheetReader(name)
|
||||
sheet, err := f.workSheetReader(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pr := sheet.SheetPr
|
||||
|
||||
for _, opt := range opts {
|
||||
opt.getSheetPrOption(pr)
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -110,7 +110,10 @@ func (o *ZoomScale) getSheetViewOption(view *xlsxSheetView) {
|
|||
|
||||
// getSheetView returns the SheetView object
|
||||
func (f *File) getSheetView(sheetName string, viewIndex int) (*xlsxSheetView, error) {
|
||||
xlsx := f.workSheetReader(sheetName)
|
||||
xlsx, err := f.workSheetReader(sheetName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if viewIndex < 0 {
|
||||
if viewIndex < -len(xlsx.SheetViews.SheetView) {
|
||||
return nil, fmt.Errorf("view index %d out of range", viewIndex)
|
||||
|
@ -120,7 +123,7 @@ func (f *File) getSheetView(sheetName string, viewIndex int) (*xlsxSheetView, er
|
|||
return nil, fmt.Errorf("view index %d out of range", viewIndex)
|
||||
}
|
||||
|
||||
return &(xlsx.SheetViews.SheetView[viewIndex]), nil
|
||||
return &(xlsx.SheetViews.SheetView[viewIndex]), err
|
||||
}
|
||||
|
||||
// SetSheetViewOptions sets sheet view options.
|
||||
|
|
17
styles.go
17
styles.go
|
@ -2266,7 +2266,10 @@ func setCellXfs(style *xlsxStyleSheet, fontID, numFmtID, fillID, borderID int, a
|
|||
// GetCellStyle provides a function to get cell style index by given worksheet
|
||||
// name and cell coordinates.
|
||||
func (f *File) GetCellStyle(sheet, axis string) (int, error) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cellData, col, _, err := f.prepareCell(xlsx, sheet, axis)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -2365,7 +2368,10 @@ func (f *File) SetCellStyle(sheet, hcell, vcell string, styleID int) error {
|
|||
vcolIdx := vcol - 1
|
||||
vrowIdx := vrow - 1
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prepareSheetXML(xlsx, vcol, vrow)
|
||||
|
||||
for r := hrowIdx; r <= vrowIdx; r++ {
|
||||
|
@ -2373,7 +2379,7 @@ func (f *File) SetCellStyle(sheet, hcell, vcell string, styleID int) error {
|
|||
xlsx.SheetData.Row[r].C[k].S = styleID
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// SetConditionalFormat provides a function to create conditional formatting
|
||||
|
@ -2605,7 +2611,10 @@ func (f *File) SetConditionalFormat(sheet, area, formatSet string) error {
|
|||
"expression": drawConfFmtExp,
|
||||
}
|
||||
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfRule := []*xlsxCfRule{}
|
||||
for p, v := range format {
|
||||
var vt, ct string
|
||||
|
|
|
@ -158,7 +158,8 @@ func TestSetConditionalFormat(t *testing.T) {
|
|||
t.Fatalf("%s", err)
|
||||
}
|
||||
|
||||
xlsx := xl.workSheetReader(sheet)
|
||||
xlsx, err := xl.workSheetReader(sheet)
|
||||
assert.NoError(t, err)
|
||||
cf := xlsx.ConditionalFormatting
|
||||
assert.Len(t, cf, 1, testCase.label)
|
||||
assert.Len(t, cf[0].CfRule, 1, testCase.label)
|
||||
|
|
7
table.go
7
table.go
|
@ -102,7 +102,7 @@ func (f *File) countTables() int {
|
|||
// addSheetTable provides a function to add tablePart element to
|
||||
// xl/worksheets/sheet%d.xml by given worksheet name and relationship index.
|
||||
func (f *File) addSheetTable(sheet string, rID int) {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, _ := f.workSheetReader(sheet)
|
||||
table := &xlsxTablePart{
|
||||
RID: "rId" + strconv.Itoa(rID),
|
||||
}
|
||||
|
@ -299,7 +299,10 @@ func (f *File) AutoFilter(sheet, hcell, vcell, format string) error {
|
|||
// autoFilter provides a function to extract the tokens from the filter
|
||||
// expression. The tokens are mainly non-whitespace groups.
|
||||
func (f *File) autoFilter(sheet, ref string, refRange, col int, formatSet *formatAutoFilter) error {
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
xlsx, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if xlsx.SheetPr != nil {
|
||||
xlsx.SheetPr.FilterMode = true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue