2016-08-30 11:51:31 +08:00
package excelize
import (
2017-08-11 23:15:33 +08:00
"fmt"
2018-07-07 15:59:48 +08:00
"image/color"
2017-01-22 16:16:03 +08:00
_ "image/gif"
_ "image/jpeg"
_ "image/png"
2017-03-28 21:18:06 +08:00
"io/ioutil"
2018-12-27 18:51:44 +08:00
"os"
2018-12-27 22:28:28 +08:00
"path/filepath"
2016-08-30 14:00:21 +08:00
"strconv"
2017-09-11 15:53:25 +08:00
"strings"
2016-08-30 11:51:31 +08:00
"testing"
2017-05-05 14:40:28 +08:00
"time"
2018-12-26 13:33:40 +08:00
"github.com/stretchr/testify/assert"
2016-08-30 11:51:31 +08:00
)
2017-01-18 14:47:23 +08:00
func TestOpenFile ( t * testing . T ) {
2016-10-19 18:42:29 +08:00
// Test update a XLSX file.
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2016-09-06 21:20:24 +08:00
}
2018-12-27 18:51:44 +08:00
2017-09-13 22:00:33 +08:00
// Test get all the rows in a not exists worksheet.
2018-12-05 00:27:19 +08:00
xlsx . GetRows ( "Sheet4" )
2017-09-13 22:00:33 +08:00
// Test get all the rows in a worksheet.
2019-03-23 20:08:06 +08:00
rows , err := xlsx . GetRows ( "Sheet2" )
assert . NoError ( t , err )
2016-11-02 12:58:51 +08:00
for _ , row := range rows {
for _ , cell := range row {
t . Log ( cell , "\t" )
}
t . Log ( "\r\n" )
}
2017-01-19 14:05:32 +08:00
xlsx . UpdateLinkedValue ( )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-09-13 22:00:33 +08:00
xlsx . SetCellDefault ( "Sheet2" , "A1" , strconv . FormatFloat ( float64 ( 100.1588 ) , 'f' , - 1 , 32 ) )
xlsx . SetCellDefault ( "Sheet2" , "A1" , strconv . FormatFloat ( float64 ( - 100.1588 ) , 'f' , - 1 , 64 ) )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-09-19 11:59:33 +08:00
// Test set cell value with illegal row number.
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetCellDefault ( "Sheet2" , "A" , strconv . FormatFloat ( float64 ( - 100.1588 ) , 'f' , - 1 , 64 ) ) ,
` cannot convert cell "A" to coordinates: invalid cell name "A" ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-09-13 22:00:33 +08:00
xlsx . SetCellInt ( "Sheet2" , "A1" , 100 )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-09-19 11:59:33 +08:00
// Test set cell integer value with illegal row number.
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetCellInt ( "Sheet2" , "A" , 100 ) , ` cannot convert cell "A" to coordinates: invalid cell name "A" ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-09-13 22:00:33 +08:00
xlsx . SetCellStr ( "Sheet2" , "C11" , "Knowns" )
2017-01-19 14:05:32 +08:00
// Test max characters in a cell.
2017-09-13 22:00:33 +08:00
xlsx . SetCellStr ( "Sheet2" , "D11" , strings . Repeat ( "c" , 32769 ) )
xlsx . NewSheet ( ":\\/?*[]Maximum 31 characters allowed in sheet title." )
// Test set worksheet name with illegal name.
2017-01-19 14:05:32 +08:00
xlsx . SetSheetName ( "Maximum 31 characters allowed i" , "[Rename]:\\/?* Maximum 31 characters allowed in sheet title." )
xlsx . SetCellInt ( "Sheet3" , "A23" , 10 )
2017-09-13 22:00:33 +08:00
xlsx . SetCellStr ( "Sheet3" , "b230" , "10" )
xlsx . SetCellStr ( "Sheet10" , "b230" , "10" )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-09-19 11:59:33 +08:00
// Test set cell string value with illegal row number.
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetCellStr ( "Sheet10" , "A" , "10" ) , ` cannot convert cell "A" to coordinates: invalid cell name "A" ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-01-19 14:05:32 +08:00
xlsx . SetActiveSheet ( 2 )
2017-09-19 11:59:33 +08:00
// Test get cell formula with given rows number.
2019-03-23 20:08:06 +08:00
_ , err = xlsx . GetCellFormula ( "Sheet1" , "B19" )
assert . NoError ( t , err )
2017-10-31 16:33:36 +08:00
// Test get cell formula with illegal worksheet name.
2019-03-23 20:08:06 +08:00
_ , err = xlsx . GetCellFormula ( "Sheet2" , "B20" )
assert . NoError ( t , err )
_ , err = xlsx . GetCellFormula ( "Sheet1" , "B20" )
assert . NoError ( t , err )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
// Test get cell formula with illegal rows number.
2019-03-23 20:08:06 +08:00
_ , err = xlsx . GetCellFormula ( "Sheet1" , "B" )
assert . EqualError ( t , err , ` cannot convert cell "B" to coordinates: invalid cell name "B" ` )
2018-05-26 16:23:15 +08:00
// Test get shared cell formula
xlsx . GetCellFormula ( "Sheet2" , "H11" )
xlsx . GetCellFormula ( "Sheet2" , "I11" )
getSharedForumula ( & xlsxWorksheet { } , "" )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2016-10-19 18:42:29 +08:00
// Test read cell value with given illegal rows number.
2019-03-23 20:08:06 +08:00
_ , err = xlsx . GetCellValue ( "Sheet2" , "a-1" )
assert . EqualError ( t , err , ` cannot convert cell "A-1" to coordinates: invalid cell name "A-1" ` )
_ , err = xlsx . GetCellValue ( "Sheet2" , "A" )
assert . EqualError ( t , err , ` cannot convert cell "A" to coordinates: invalid cell name "A" ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2016-10-19 18:42:29 +08:00
// Test read cell value with given lowercase column number.
2017-01-19 14:05:32 +08:00
xlsx . GetCellValue ( "Sheet2" , "a5" )
xlsx . GetCellValue ( "Sheet2" , "C11" )
xlsx . GetCellValue ( "Sheet2" , "D11" )
xlsx . GetCellValue ( "Sheet2" , "D12" )
2016-10-19 18:42:29 +08:00
// Test SetCellValue function.
2017-03-28 11:48:09 +08:00
xlsx . SetCellValue ( "Sheet2" , "F1" , " Hello" )
2017-01-19 14:05:32 +08:00
xlsx . SetCellValue ( "Sheet2" , "G1" , [ ] byte ( "World" ) )
xlsx . SetCellValue ( "Sheet2" , "F2" , 42 )
2017-10-18 18:42:20 +08:00
xlsx . SetCellValue ( "Sheet2" , "F3" , int8 ( 1 << 8 / 2 - 1 ) )
xlsx . SetCellValue ( "Sheet2" , "F4" , int16 ( 1 << 16 / 2 - 1 ) )
xlsx . SetCellValue ( "Sheet2" , "F5" , int32 ( 1 << 32 / 2 - 1 ) )
xlsx . SetCellValue ( "Sheet2" , "F6" , int64 ( 1 << 32 / 2 - 1 ) )
xlsx . SetCellValue ( "Sheet2" , "F7" , float32 ( 42.65418 ) )
xlsx . SetCellValue ( "Sheet2" , "F8" , float64 ( - 42.65418 ) )
xlsx . SetCellValue ( "Sheet2" , "F9" , float32 ( 42 ) )
xlsx . SetCellValue ( "Sheet2" , "F10" , float64 ( 42 ) )
xlsx . SetCellValue ( "Sheet2" , "F11" , uint ( 1 << 32 - 1 ) )
xlsx . SetCellValue ( "Sheet2" , "F12" , uint8 ( 1 << 8 - 1 ) )
xlsx . SetCellValue ( "Sheet2" , "F13" , uint16 ( 1 << 16 - 1 ) )
xlsx . SetCellValue ( "Sheet2" , "F14" , uint32 ( 1 << 32 - 1 ) )
xlsx . SetCellValue ( "Sheet2" , "F15" , uint64 ( 1 << 32 - 1 ) )
xlsx . SetCellValue ( "Sheet2" , "F16" , true )
2018-05-14 10:12:46 +08:00
xlsx . SetCellValue ( "Sheet2" , "F17" , complex64 ( 5 + 10i ) )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2018-01-26 01:06:40 +08:00
// Test boolean write
booltest := [ ] struct {
value bool
expected string
} {
{ false , "0" } ,
{ true , "1" } ,
}
for _ , test := range booltest {
xlsx . SetCellValue ( "Sheet2" , "F16" , test . value )
2019-03-23 20:08:06 +08:00
val , err := xlsx . GetCellValue ( "Sheet2" , "F16" )
assert . NoError ( t , err )
assert . Equal ( t , test . expected , val )
2018-01-26 01:06:40 +08:00
}
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-01-19 14:05:32 +08:00
xlsx . SetCellValue ( "Sheet2" , "G2" , nil )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetCellValue ( "Sheet2" , "G4" , time . Now ( ) ) , "only UTC time expected" )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetCellValue ( "Sheet2" , "G4" , time . Now ( ) . UTC ( ) )
2018-01-05 09:39:31 +08:00
// 02:46:40
xlsx . SetCellValue ( "Sheet2" , "G5" , time . Duration ( 1e13 ) )
2016-10-23 16:07:57 +08:00
// Test completion column.
2017-01-19 14:05:32 +08:00
xlsx . SetCellValue ( "Sheet2" , "M2" , nil )
2016-10-19 18:42:29 +08:00
// Test read cell value with given axis large than exists row.
2017-01-19 14:05:32 +08:00
xlsx . GetCellValue ( "Sheet2" , "E231" )
2017-09-13 22:00:33 +08:00
// Test get active worksheet of XLSX and get worksheet name of XLSX by given worksheet index.
2017-01-19 14:05:32 +08:00
xlsx . GetSheetName ( xlsx . GetActiveSheetIndex ( ) )
2017-09-13 22:00:33 +08:00
// Test get worksheet index of XLSX by given worksheet name.
2017-04-01 21:02:25 +08:00
xlsx . GetSheetIndex ( "Sheet1" )
2017-09-13 22:00:33 +08:00
// Test get worksheet name of XLSX by given invalid worksheet index.
2017-01-19 14:05:32 +08:00
xlsx . GetSheetName ( 4 )
2017-09-13 22:00:33 +08:00
// Test get worksheet map of XLSX.
2017-01-19 14:05:32 +08:00
xlsx . GetSheetMap ( )
2016-09-05 16:37:15 +08:00
for i := 1 ; i <= 300 ; i ++ {
2017-09-13 22:00:33 +08:00
xlsx . SetCellStr ( "Sheet3" , "c" + strconv . Itoa ( i ) , strconv . Itoa ( i ) )
2017-01-19 14:05:32 +08:00
}
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestOpenFile.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
}
2019-01-01 13:20:14 +08:00
func TestSaveFile ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2019-01-01 13:20:14 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSaveFile.xlsx" ) ) )
xlsx , err = OpenFile ( filepath . Join ( "test" , "TestSaveFile.xlsx" ) )
2019-01-01 13:20:14 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
assert . NoError ( t , xlsx . Save ( ) )
}
2018-12-27 18:51:44 +08:00
func TestSaveAsWrongPath ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if assert . NoError ( t , err ) {
// Test write file to not exist directory.
err = xlsx . SaveAs ( "" )
if assert . Error ( t , err ) {
assert . True ( t , os . IsNotExist ( err ) , "Error: %v: Expected os.IsNotExists(err) == true" , err )
}
2016-08-30 11:51:31 +08:00
}
2017-01-19 14:05:32 +08:00
}
func TestAddPicture ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2016-08-30 11:51:31 +08:00
}
2018-12-27 18:51:44 +08:00
2018-02-03 15:02:37 +08:00
// Test add picture to worksheet with offset and location hyperlink.
2018-12-27 22:28:28 +08:00
err = xlsx . AddPicture ( "Sheet2" , "I9" , filepath . Join ( "test" , "images" , "excel.jpg" ) ,
2018-12-27 18:51:44 +08:00
` { "x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"} ` )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-01-17 19:06:42 +08:00
}
2018-12-27 18:51:44 +08:00
2018-04-26 11:41:13 +08:00
// Test add picture to worksheet with offset, external hyperlink and positioning.
2018-12-27 22:28:28 +08:00
err = xlsx . AddPicture ( "Sheet1" , "F21" , filepath . Join ( "test" , "images" , "excel.jpg" ) ,
2018-12-27 18:51:44 +08:00
` { "x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"} ` )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-01-17 19:06:42 +08:00
}
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
file , err := ioutil . ReadFile ( filepath . Join ( "test" , "images" , "excel.jpg" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
// Test add picture to worksheet from bytes.
err = xlsx . AddPictureFromBytes ( "Sheet1" , "Q1" , "" , "Excel Logo" , ".jpg" , file )
assert . NoError ( t , err )
// Test write file to given path.
2018-12-27 22:28:28 +08:00
err = xlsx . SaveAs ( filepath . Join ( "test" , "TestAddPicture.xlsx" ) )
2018-12-27 18:51:44 +08:00
assert . NoError ( t , err )
}
func TestAddPictureErrors ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2018-02-03 15:02:37 +08:00
// Test add picture to worksheet with invalid file path.
2018-12-27 22:28:28 +08:00
err = xlsx . AddPicture ( "Sheet1" , "G21" , filepath . Join ( "test" , "not_exists_dir" , "not_exists.icon" ) , "" )
2018-12-27 18:51:44 +08:00
if assert . Error ( t , err ) {
assert . True ( t , os . IsNotExist ( err ) , "Expected os.IsNotExist(err) == true" )
2017-01-17 19:06:42 +08:00
}
2018-12-27 18:51:44 +08:00
2018-02-03 15:02:37 +08:00
// Test add picture to worksheet with unsupport file type.
2018-12-27 22:28:28 +08:00
err = xlsx . AddPicture ( "Sheet1" , "G21" , filepath . Join ( "test" , "Book1.xlsx" ) , "" )
2018-12-27 18:51:44 +08:00
assert . EqualError ( t , err , "unsupported image extension" )
2018-09-14 00:24:49 +08:00
err = xlsx . AddPictureFromBytes ( "Sheet1" , "G21" , "" , "Excel Logo" , "jpg" , make ( [ ] byte , 1 ) )
2018-12-27 18:51:44 +08:00
assert . EqualError ( t , err , "unsupported image extension" )
2018-09-14 00:24:49 +08:00
// Test add picture to worksheet with invalid file data.
err = xlsx . AddPictureFromBytes ( "Sheet1" , "G21" , "" , "Excel Logo" , ".jpg" , make ( [ ] byte , 1 ) )
2018-12-27 18:51:44 +08:00
assert . EqualError ( t , err , "image: unknown format" )
2017-01-18 16:05:01 +08:00
}
2016-08-30 11:51:31 +08:00
2017-01-18 16:05:01 +08:00
func TestBrokenFile ( t * testing . T ) {
2016-10-19 18:42:29 +08:00
// Test write file with broken file struct.
2017-01-19 14:05:32 +08:00
xlsx := File { }
2016-10-19 18:42:29 +08:00
2018-12-27 18:51:44 +08:00
t . Run ( "SaveWithoutName" , func ( t * testing . T ) {
assert . EqualError ( t , xlsx . Save ( ) , "no path defined for file, consider File.WriteTo or File.Write" )
} )
2017-01-18 16:05:01 +08:00
2018-12-27 18:51:44 +08:00
t . Run ( "SaveAsEmptyStruct" , func ( t * testing . T ) {
// Test write file with broken file struct with given path.
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestBrokenFile.SaveAsEmptyStruct.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
} )
t . Run ( "OpenBadWorkbook" , func ( t * testing . T ) {
// Test set active sheet without BookViews and Sheets maps in xl/workbook.xml.
2018-12-27 22:28:28 +08:00
f3 , err := OpenFile ( filepath . Join ( "test" , "BadWorkbook.xlsx" ) )
2018-12-27 18:51:44 +08:00
f3 . GetActiveSheetIndex ( )
f3 . SetActiveSheet ( 2 )
assert . NoError ( t , err )
} )
t . Run ( "OpenNotExistsFile" , func ( t * testing . T ) {
// Test open a XLSX file with given illegal path.
2018-12-27 22:28:28 +08:00
_ , err := OpenFile ( filepath . Join ( "test" , "NotExistsFile.xlsx" ) )
2018-12-27 18:51:44 +08:00
if assert . Error ( t , err ) {
assert . True ( t , os . IsNotExist ( err ) , "Expected os.IsNotExists(err) == true" )
}
} )
2017-01-18 16:05:01 +08:00
}
2017-06-28 17:03:20 +08:00
func TestNewFile ( t * testing . T ) {
2017-01-18 16:05:01 +08:00
// Test create a XLSX file.
2017-06-28 17:03:20 +08:00
xlsx := NewFile ( )
2018-03-16 20:54:07 +08:00
xlsx . NewSheet ( "Sheet1" )
2017-09-13 22:00:33 +08:00
xlsx . NewSheet ( "XLSXSheet2" )
xlsx . NewSheet ( "XLSXSheet3" )
xlsx . SetCellInt ( "XLSXSheet2" , "A23" , 56 )
xlsx . SetCellStr ( "Sheet1" , "B20" , "42" )
2017-01-19 14:05:32 +08:00
xlsx . SetActiveSheet ( 0 )
2018-12-27 18:51:44 +08:00
2018-04-26 11:41:13 +08:00
// Test add picture to sheet with scaling and positioning.
2018-12-27 22:28:28 +08:00
err := xlsx . AddPicture ( "Sheet1" , "H2" , filepath . Join ( "test" , "images" , "excel.gif" ) ,
` { "x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2016-08-30 11:51:31 +08:00
}
2018-12-27 18:51:44 +08:00
2018-09-14 00:24:49 +08:00
// Test add picture to worksheet without formatset.
2018-12-27 22:28:28 +08:00
err = xlsx . AddPicture ( "Sheet1" , "C2" , filepath . Join ( "test" , "images" , "excel.png" ) , "" )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-09-14 00:24:49 +08:00
}
2018-12-27 18:51:44 +08:00
2018-09-14 00:24:49 +08:00
// Test add picture to worksheet with invalid formatset.
2018-12-27 22:28:28 +08:00
err = xlsx . AddPicture ( "Sheet1" , "C2" , filepath . Join ( "test" , "images" , "excel.png" ) , ` { ` )
2018-12-27 18:51:44 +08:00
if ! assert . Error ( t , err ) {
t . FailNow ( )
2016-09-06 21:20:24 +08:00
}
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestNewFile.xlsx" ) ) )
2016-08-30 11:51:31 +08:00
}
2017-01-18 14:47:23 +08:00
2017-06-29 11:14:33 +08:00
func TestColWidth ( t * testing . T ) {
2017-06-28 17:03:20 +08:00
xlsx := NewFile ( )
2017-09-13 22:00:33 +08:00
xlsx . SetColWidth ( "Sheet1" , "B" , "A" , 12 )
xlsx . SetColWidth ( "Sheet1" , "A" , "B" , 12 )
xlsx . GetColWidth ( "Sheet1" , "A" )
xlsx . GetColWidth ( "Sheet1" , "C" )
2018-12-27 22:28:28 +08:00
err := xlsx . SaveAs ( filepath . Join ( "test" , "TestColWidth.xlsx" ) )
2017-01-19 14:05:32 +08:00
if err != nil {
2018-05-07 16:14:35 +08:00
t . Error ( err )
2017-01-19 14:05:32 +08:00
}
2017-06-29 11:14:33 +08:00
convertRowHeightToPixels ( 0 )
}
2017-01-19 14:05:32 +08:00
func TestSetCellHyperLink ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2017-01-19 14:05:32 +08:00
if err != nil {
t . Log ( err )
}
// Test set cell hyperlink in a work sheet already have hyperlinks.
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellHyperLink ( "Sheet1" , "B19" , "https://github.com/360EntSecGroup-Skylar/excelize" , "External" ) )
2017-01-19 14:05:32 +08:00
// Test add first hyperlink in a work sheet.
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellHyperLink ( "Sheet2" , "C1" , "https://github.com/360EntSecGroup-Skylar/excelize" , "External" ) )
2017-07-30 15:46:04 +08:00
// Test add Location hyperlink in a work sheet.
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellHyperLink ( "Sheet2" , "D6" , "Sheet1!D8" , "Location" ) )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetCellHyperLink ( "Sheet2" , "C3" , "Sheet1!D8" , "" ) , ` invalid link type "" ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetCellHyperLink ( "Sheet2" , "" , "Sheet1!D60" , "Location" ) , ` invalid cell name "" ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellHyperLink.xlsx" ) ) )
2017-01-19 14:05:32 +08:00
}
2017-08-08 20:08:54 +08:00
func TestGetCellHyperLink ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-08-08 20:08:54 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
link , target , err := xlsx . GetCellHyperLink ( "Sheet1" , "" )
assert . EqualError ( t , err , ` invalid cell name "" ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2019-03-23 20:08:06 +08:00
link , target , err = xlsx . GetCellHyperLink ( "Sheet1" , "A22" )
assert . NoError ( t , err )
2017-08-08 20:08:54 +08:00
t . Log ( link , target )
2019-03-23 20:08:06 +08:00
link , target , err = xlsx . GetCellHyperLink ( "Sheet2" , "D6" )
assert . NoError ( t , err )
2017-08-08 20:08:54 +08:00
t . Log ( link , target )
2019-03-23 20:08:06 +08:00
link , target , err = xlsx . GetCellHyperLink ( "Sheet3" , "H3" )
assert . NoError ( t , err )
2017-08-08 20:08:54 +08:00
t . Log ( link , target )
}
2017-01-19 14:05:32 +08:00
func TestSetCellFormula ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-01-18 14:47:23 +08:00
}
2018-12-27 18:51:44 +08:00
2017-09-13 22:00:33 +08:00
xlsx . SetCellFormula ( "Sheet1" , "B19" , "SUM(Sheet2!D2,Sheet2!D11)" )
xlsx . SetCellFormula ( "Sheet1" , "C19" , "SUM(Sheet2!D2,Sheet2!D9)" )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-09-19 11:59:33 +08:00
// Test set cell formula with illegal rows number.
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetCellFormula ( "Sheet1" , "C" , "SUM(Sheet2!D2,Sheet2!D9)" ) , ` cannot convert cell "C" to coordinates: invalid cell name "C" ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2019-02-22 22:17:38 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellFormula1.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
2019-02-22 22:17:38 +08:00
xlsx , err = OpenFile ( filepath . Join ( "test" , "CalcChain.xlsx" ) )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
// Test remove cell formula.
xlsx . SetCellFormula ( "Sheet1" , "A1" , "" )
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellFormula2.xlsx" ) ) )
// Test remove all cell formula.
xlsx . SetCellFormula ( "Sheet1" , "B1" , "" )
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellFormula3.xlsx" ) ) )
2017-01-18 14:47:23 +08:00
}
2017-01-24 18:29:02 +08:00
func TestSetSheetBackground ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-01-24 18:29:02 +08:00
}
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
err = xlsx . SetSheetBackground ( "Sheet2" , filepath . Join ( "test" , "images" , "background.jpg" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-01-24 18:29:02 +08:00
}
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
err = xlsx . SetSheetBackground ( "Sheet2" , filepath . Join ( "test" , "images" , "background.jpg" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-01-24 18:29:02 +08:00
}
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetSheetBackground.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
}
func TestSetSheetBackgroundErrors ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-01-24 18:29:02 +08:00
}
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
err = xlsx . SetSheetBackground ( "Sheet2" , filepath . Join ( "test" , "not_exists" , "not_exists.png" ) )
2018-12-27 18:51:44 +08:00
if assert . Error ( t , err ) {
assert . True ( t , os . IsNotExist ( err ) , "Expected os.IsNotExists(err) == true" )
}
2018-12-27 22:28:28 +08:00
err = xlsx . SetSheetBackground ( "Sheet2" , filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
assert . EqualError ( t , err , "unsupported image extension" )
2017-01-24 18:29:02 +08:00
}
2017-01-25 15:44:18 +08:00
2017-02-12 19:03:24 +08:00
func TestMergeCell ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-01-25 15:44:18 +08:00
}
2018-12-27 18:51:44 +08:00
2017-01-25 18:13:11 +08:00
xlsx . MergeCell ( "Sheet1" , "D9" , "D9" )
xlsx . MergeCell ( "Sheet1" , "D9" , "E9" )
xlsx . MergeCell ( "Sheet1" , "H14" , "G13" )
xlsx . MergeCell ( "Sheet1" , "C9" , "D8" )
xlsx . MergeCell ( "Sheet1" , "F11" , "G13" )
xlsx . MergeCell ( "Sheet1" , "H7" , "B15" )
xlsx . MergeCell ( "Sheet1" , "D11" , "F13" )
xlsx . MergeCell ( "Sheet1" , "G10" , "K12" )
xlsx . SetCellValue ( "Sheet1" , "G11" , "set value in merged cell" )
xlsx . SetCellInt ( "Sheet1" , "H11" , 100 )
xlsx . SetCellValue ( "Sheet1" , "I11" , float64 ( 0.5 ) )
2017-11-16 11:07:39 +08:00
xlsx . SetCellHyperLink ( "Sheet1" , "J11" , "https://github.com/360EntSecGroup-Skylar/excelize" , "External" )
2017-01-25 18:13:11 +08:00
xlsx . SetCellFormula ( "Sheet1" , "G12" , "SUM(Sheet1!B19,Sheet1!C19)" )
xlsx . GetCellValue ( "Sheet1" , "H11" )
2018-04-08 10:31:11 +08:00
xlsx . GetCellValue ( "Sheet2" , "A6" ) // Merged cell ref is single coordinate.
2017-01-25 18:13:11 +08:00
xlsx . GetCellFormula ( "Sheet1" , "G12" )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestMergeCell.xlsx" ) ) )
2017-01-25 15:44:18 +08:00
}
2017-02-02 10:59:31 +08:00
2018-12-19 19:54:38 +08:00
func TestGetMergeCells ( t * testing . T ) {
wants := [ ] struct {
value string
start string
end string
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
} { {
value : "A1" ,
start : "A1" ,
end : "B1" ,
} , {
value : "A2" ,
start : "A2" ,
end : "A3" ,
} , {
value : "A4" ,
start : "A4" ,
end : "B5" ,
} , {
value : "A7" ,
start : "A7" ,
end : "C10" ,
} }
2018-12-19 19:54:38 +08:00
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "MergeCell.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-12-19 19:54:38 +08:00
}
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
sheet1 := xlsx . GetSheetName ( 1 )
2018-12-19 19:54:38 +08:00
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
mergeCells := xlsx . GetMergeCells ( sheet1 )
if ! assert . Len ( t , mergeCells , len ( wants ) ) {
t . FailNow ( )
2018-12-19 19:54:38 +08:00
}
for i , m := range mergeCells {
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
assert . Equal ( t , wants [ i ] . value , m . GetCellValue ( ) )
assert . Equal ( t , wants [ i ] . start , m . GetStartAxis ( ) )
assert . Equal ( t , wants [ i ] . end , m . GetEndAxis ( ) )
2018-12-19 19:54:38 +08:00
}
}
2017-03-26 15:27:04 +08:00
func TestSetCellStyleAlignment ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-26 15:27:04 +08:00
}
2018-12-27 18:51:44 +08:00
2017-06-29 19:41:00 +08:00
var style int
style , err = xlsx . NewStyle ( ` { "alignment": { "horizontal":"center","ident":1,"justify_last_line":true,"reading_order":0,"relative_indent":1,"shrink_to_fit":true,"text_rotation":45,"vertical":"top","wrap_text":true}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-06-29 19:41:00 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "A22" , "A22" , style ) )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-09-19 11:59:33 +08:00
// Test set cell style with given illegal rows number.
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetCellStyle ( "Sheet1" , "A" , "A22" , style ) , ` cannot convert cell "A" to coordinates: invalid cell name "A" ` )
assert . EqualError ( t , xlsx . SetCellStyle ( "Sheet1" , "A22" , "A" , style ) , ` cannot convert cell "A" to coordinates: invalid cell name "A" ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2017-09-19 11:59:33 +08:00
// Test get cell style with given illegal rows number.
2019-03-23 20:08:06 +08:00
index , err := xlsx . GetCellStyle ( "Sheet1" , "A" )
assert . Equal ( t , 0 , index )
assert . EqualError ( t , err , ` cannot convert cell "A" to coordinates: invalid cell name "A" ` )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellStyleAlignment.xlsx" ) ) )
2017-03-26 15:27:04 +08:00
}
func TestSetCellStyleBorder ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-06 12:05:41 +08:00
}
2017-06-29 19:41:00 +08:00
2018-12-27 18:51:44 +08:00
var style int
2017-06-29 19:41:00 +08:00
2017-03-19 17:14:40 +08:00
// Test set border on overlapping area with vertical variants shading styles gradient fill.
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "border":[ { "type":"left","color":"0000FF","style":2}, { "type":"top","color":"00FF00","style":12}, { "type":"bottom","color":"FFFF00","style":5}, { "type":"right","color":"FF0000","style":6}, { "type":"diagonalDown","color":"A020F0","style":9}, { "type":"diagonalUp","color":"A020F0","style":8}]} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-06 12:05:41 +08:00
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "J21" , "L25" , style ) )
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "border":[ { "type":"left","color":"0000FF","style":2}, { "type":"top","color":"00FF00","style":3}, { "type":"bottom","color":"FFFF00","style":4}, { "type":"right","color":"FF0000","style":5}, { "type":"diagonalDown","color":"A020F0","style":6}, { "type":"diagonalUp","color":"A020F0","style":7}],"fill": { "type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":1}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-06 12:05:41 +08:00
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "M28" , "K24" , style ) )
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "border":[ { "type":"left","color":"0000FF","style":2}, { "type":"top","color":"00FF00","style":3}, { "type":"bottom","color":"FFFF00","style":4}, { "type":"right","color":"FF0000","style":5}, { "type":"diagonalDown","color":"A020F0","style":6}, { "type":"diagonalUp","color":"A020F0","style":7}],"fill": { "type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":4}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-06-29 19:41:00 +08:00
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "M28" , "K24" , style ) )
2017-06-29 19:41:00 +08:00
2017-03-19 17:14:40 +08:00
// Test set border and solid style pattern fill for a single cell.
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "border":[ { "type":"left","color":"0000FF","style":8}, { "type":"top","color":"00FF00","style":9}, { "type":"bottom","color":"FFFF00","style":10}, { "type":"right","color":"FF0000","style":11}, { "type":"diagonalDown","color":"A020F0","style":12}, { "type":"diagonalUp","color":"A020F0","style":13}],"fill": { "type":"pattern","color":["#E0EBF5"],"pattern":1}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-19 17:14:40 +08:00
}
2017-06-29 19:41:00 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "O22" , "O22" , style ) )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellStyleBorder.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
}
func TestSetCellStyleBorderErrors ( t * testing . T ) {
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
// Set border with invalid style parameter.
_ , err = xlsx . NewStyle ( "" )
if ! assert . EqualError ( t , err , "unexpected end of JSON input" ) {
t . FailNow ( )
}
// Set border with invalid style index number.
_ , err = xlsx . NewStyle ( ` { "border":[ { "type":"left","color":"0000FF","style":-1}, { "type":"top","color":"00FF00","style":14}, { "type":"bottom","color":"FFFF00","style":5}, { "type":"right","color":"FF0000","style":6}, { "type":"diagonalDown","color":"A020F0","style":9}, { "type":"diagonalUp","color":"A020F0","style":8}]} ` )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-19 17:14:40 +08:00
}
}
2017-05-05 14:40:28 +08:00
func TestSetCellStyleNumberFormat ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-19 17:14:40 +08:00
}
2018-12-27 18:51:44 +08:00
2017-04-07 17:32:14 +08:00
// Test only set fill and number format for a cell.
2017-05-05 14:40:28 +08:00
col := [ ] string { "L" , "M" , "N" , "O" , "P" }
data := [ ] int { 0 , 1 , 2 , 3 , 4 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 }
value := [ ] string { "37947.7500001" , "-37947.7500001" , "0.007" , "2.1" , "String" }
for i , v := range value {
for k , d := range data {
c := col [ i ] + strconv . Itoa ( k + 1 )
var val float64
val , err = strconv . ParseFloat ( v , 64 )
if err != nil {
xlsx . SetCellValue ( "Sheet2" , c , v )
} else {
xlsx . SetCellValue ( "Sheet2" , c , val )
}
2017-06-29 19:41:00 +08:00
style , err := xlsx . NewStyle ( ` { "fill": { "type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":5},"number_format": ` + strconv . Itoa ( d ) + ` } ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-05-05 14:40:28 +08:00
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet2" , c , c , style ) )
2017-05-05 14:40:28 +08:00
t . Log ( xlsx . GetCellValue ( "Sheet2" , c ) )
}
}
2017-06-29 19:41:00 +08:00
var style int
style , err = xlsx . NewStyle ( ` { "number_format":-1} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-06-29 19:41:00 +08:00
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet2" , "L33" , "L33" , style ) )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellStyleNumberFormat.xlsx" ) ) )
2017-05-05 14:40:28 +08:00
}
2017-07-14 21:15:44 +08:00
func TestSetCellStyleCurrencyNumberFormat ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
t . Run ( "TestBook3" , func ( t * testing . T ) {
xlsx , err := prepareTestBook3 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2017-07-14 21:15:44 +08:00
2018-12-27 18:51:44 +08:00
xlsx . SetCellValue ( "Sheet1" , "A1" , 56 )
xlsx . SetCellValue ( "Sheet1" , "A2" , - 32.3 )
var style int
style , err = xlsx . NewStyle ( ` { "number_format": 188, "decimal_places": -1} ` )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2017-07-14 21:15:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "A1" , "A1" , style ) )
2018-12-27 18:51:44 +08:00
style , err = xlsx . NewStyle ( ` { "number_format": 188, "decimal_places": 31, "negred": true} ` )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2017-07-14 21:15:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "A2" , "A2" , style ) )
2017-07-14 21:15:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellStyleCurrencyNumberFormat.TestBook3.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
} )
2017-07-14 21:15:44 +08:00
2018-12-27 18:51:44 +08:00
t . Run ( "TestBook4" , func ( t * testing . T ) {
xlsx , err := prepareTestBook4 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
xlsx . SetCellValue ( "Sheet1" , "A1" , 42920.5 )
xlsx . SetCellValue ( "Sheet1" , "A2" , 42920.5 )
_ , err = xlsx . NewStyle ( ` { "number_format": 26, "lang": "zh-tw"} ` )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
style , err := xlsx . NewStyle ( ` { "number_format": 27} ` )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "A1" , "A1" , style ) )
2018-12-27 18:51:44 +08:00
style , err = xlsx . NewStyle ( ` { "number_format": 31, "lang": "ko-kr"} ` )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "A2" , "A2" , style ) )
2018-12-27 18:51:44 +08:00
style , err = xlsx . NewStyle ( ` { "number_format": 71, "lang": "th-th"} ` )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "A2" , "A2" , style ) )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellStyleCurrencyNumberFormat.TestBook4.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
} )
2017-07-14 21:15:44 +08:00
}
2017-07-27 11:46:04 +08:00
func TestSetCellStyleCustomNumberFormat ( t * testing . T ) {
xlsx := NewFile ( )
xlsx . SetCellValue ( "Sheet1" , "A1" , 42920.5 )
xlsx . SetCellValue ( "Sheet1" , "A2" , 42920.5 )
style , err := xlsx . NewStyle ( ` { "custom_number_format": "[$-380A]dddd\\,\\ dd\" de \"mmmm\" de \"yyyy;@"} ` )
if err != nil {
t . Log ( err )
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "A1" , "A1" , style ) )
2017-07-27 11:46:04 +08:00
style , err = xlsx . NewStyle ( ` { "custom_number_format": "[$-380A]dddd\\,\\ dd\" de \"mmmm\" de \"yyyy;@"} ` )
if err != nil {
t . Log ( err )
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "A2" , "A2" , style ) )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellStyleCustomNumberFormat.xlsx" ) ) )
2017-07-27 11:46:04 +08:00
}
2017-05-05 14:40:28 +08:00
func TestSetCellStyleFill ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-19 17:14:40 +08:00
}
2018-12-27 18:51:44 +08:00
2017-06-29 19:41:00 +08:00
var style int
2017-03-19 17:14:40 +08:00
// Test set fill for cell with invalid parameter.
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "fill": { "type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":6}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-19 17:14:40 +08:00
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "O23" , "O23" , style ) )
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "fill": { "type":"gradient","color":["#FFFFFF"],"shading":1}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-19 17:14:40 +08:00
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "O23" , "O23" , style ) )
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "fill": { "type":"pattern","color":[],"pattern":1}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-19 17:14:40 +08:00
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "O23" , "O23" , style ) )
2017-04-07 17:32:14 +08:00
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "fill": { "type":"pattern","color":["#E0EBF5"],"pattern":19}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-06 12:05:41 +08:00
}
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet1" , "O23" , "O23" , style ) )
2017-06-29 19:41:00 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellStyleFill.xlsx" ) ) )
2017-04-25 18:43:10 +08:00
}
func TestSetCellStyleFont ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-25 18:43:10 +08:00
}
2018-12-27 18:51:44 +08:00
2017-06-29 19:41:00 +08:00
var style int
style , err = xlsx . NewStyle ( ` { "font": { "bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-25 18:43:10 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet2" , "A1" , "A1" , style ) )
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "font": { "italic":true,"underline":"double"}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-25 18:43:10 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet2" , "A2" , "A2" , style ) )
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "font": { "bold":true}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-25 18:43:10 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet2" , "A3" , "A3" , style ) )
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "font": { "bold":true,"family":"","size":0,"color":"","underline":""}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-25 18:43:10 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet2" , "A4" , "A4" , style ) )
2017-06-29 19:41:00 +08:00
style , err = xlsx . NewStyle ( ` { "font": { "color":"#777777"}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-25 18:43:10 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet2" , "A5" , "A5" , style ) )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellStyleFont.xlsx" ) ) )
2017-03-06 12:05:41 +08:00
}
2017-03-22 18:51:18 +08:00
2018-03-07 12:56:18 +08:00
func TestSetCellStyleProtection ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-03-07 12:56:18 +08:00
}
2018-12-27 18:51:44 +08:00
2018-03-07 12:56:18 +08:00
var style int
style , err = xlsx . NewStyle ( ` { "protection": { "hidden":true, "locked":true}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-03-07 12:56:18 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . SetCellStyle ( "Sheet2" , "A6" , "A6" , style ) )
2018-12-27 22:28:28 +08:00
err = xlsx . SaveAs ( filepath . Join ( "test" , "TestSetCellStyleProtection.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-03-07 12:56:18 +08:00
}
}
2018-12-27 18:51:44 +08:00
func TestSetDeleteSheet ( t * testing . T ) {
t . Run ( "TestBook3" , func ( t * testing . T ) {
xlsx , err := prepareTestBook3 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
xlsx . DeleteSheet ( "XLSXSheet3" )
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetDeleteSheet.TestBook3.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
} )
t . Run ( "TestBook4" , func ( t * testing . T ) {
xlsx , err := prepareTestBook4 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
xlsx . DeleteSheet ( "Sheet1" )
xlsx . AddComment ( "Sheet1" , "A1" , "" )
xlsx . AddComment ( "Sheet1" , "A1" , ` { "author":"Excelize: ","text":"This is a comment."} ` )
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetDeleteSheet.TestBook4.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
} )
2017-03-22 18:51:18 +08:00
}
2017-03-28 21:18:06 +08:00
func TestGetPicture ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-03-28 21:18:06 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
file , raw , err := xlsx . GetPicture ( "Sheet1" , "F21" )
assert . NoError ( t , err )
2019-03-20 16:52:33 +08:00
if ! assert . NotEmpty ( t , filepath . Join ( "test" , file ) ) || ! assert . NotEmpty ( t , raw ) ||
! assert . NoError ( t , ioutil . WriteFile ( filepath . Join ( "test" , file ) , raw , 0644 ) ) {
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
t . FailNow ( )
2017-03-28 21:18:06 +08:00
}
2018-12-27 18:51:44 +08:00
2017-03-28 21:18:06 +08:00
// Try to get picture from a worksheet that doesn't contain any images.
2019-03-23 20:08:06 +08:00
file , raw , err = xlsx . GetPicture ( "Sheet3" , "I9" )
assert . NoError ( t , err )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
assert . Empty ( t , file )
assert . Empty ( t , raw )
2017-03-28 21:18:06 +08:00
// Try to get picture from a cell that doesn't contain an image.
2019-03-23 20:08:06 +08:00
file , raw , err = xlsx . GetPicture ( "Sheet2" , "A2" )
assert . NoError ( t , err )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
assert . Empty ( t , file )
assert . Empty ( t , raw )
2017-08-01 16:35:18 +08:00
xlsx . getDrawingRelationships ( "xl/worksheets/_rels/sheet1.xml.rels" , "rId8" )
xlsx . getDrawingRelationships ( "" , "" )
xlsx . getSheetRelationshipsTargetByID ( "" , "" )
2017-10-31 16:33:36 +08:00
xlsx . deleteSheetRelationships ( "" , "" )
2019-02-25 22:14:34 +08:00
// Try to get picture from a local storage file.
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
if ! assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestGetPicture.xlsx" ) ) ) {
t . FailNow ( )
}
2019-02-25 22:14:34 +08:00
xlsx , err = OpenFile ( filepath . Join ( "test" , "TestGetPicture.xlsx" ) )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2019-03-23 20:08:06 +08:00
file , raw , err = xlsx . GetPicture ( "Sheet1" , "F21" )
assert . NoError ( t , err )
2019-03-20 16:52:33 +08:00
if ! assert . NotEmpty ( t , filepath . Join ( "test" , file ) ) || ! assert . NotEmpty ( t , raw ) ||
! assert . NoError ( t , ioutil . WriteFile ( filepath . Join ( "test" , file ) , raw , 0644 ) ) {
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
t . FailNow ( )
2019-02-25 22:14:34 +08:00
}
// Try to get picture from a local storage file that doesn't contain an image.
2019-03-23 20:08:06 +08:00
file , raw , err = xlsx . GetPicture ( "Sheet1" , "F22" )
assert . NoError ( t , err )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
assert . Empty ( t , file )
assert . Empty ( t , raw )
2017-03-28 21:18:06 +08:00
}
2017-04-04 19:12:35 +08:00
2017-04-26 11:43:39 +08:00
func TestSheetVisibility ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-26 11:43:39 +08:00
}
2018-12-27 18:51:44 +08:00
2017-06-14 15:01:49 +08:00
xlsx . SetSheetVisible ( "Sheet2" , false )
xlsx . SetSheetVisible ( "Sheet1" , false )
xlsx . SetSheetVisible ( "Sheet1" , true )
xlsx . GetSheetVisible ( "Sheet1" )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSheetVisibility.xlsx" ) ) )
2017-04-26 11:43:39 +08:00
}
2017-06-15 11:03:29 +08:00
func TestColumnVisibility ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
t . Run ( "TestBook1" , func ( t * testing . T ) {
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
xlsx . SetColVisible ( "Sheet1" , "F" , false )
xlsx . SetColVisible ( "Sheet1" , "F" , true )
xlsx . GetColVisible ( "Sheet1" , "F" )
xlsx . SetColVisible ( "Sheet3" , "E" , false )
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestColumnVisibility.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
} )
t . Run ( "TestBook3" , func ( t * testing . T ) {
xlsx , err := prepareTestBook3 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
xlsx . GetColVisible ( "Sheet1" , "B" )
} )
2017-06-15 11:03:29 +08:00
}
2017-04-04 19:12:35 +08:00
func TestCopySheet ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-04 19:12:35 +08:00
}
2018-12-27 18:51:44 +08:00
2017-09-13 22:00:33 +08:00
idx := xlsx . NewSheet ( "CopySheet" )
err = xlsx . CopySheet ( 1 , idx )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-04 19:12:35 +08:00
}
2018-12-27 18:51:44 +08:00
2017-08-19 13:37:15 +08:00
xlsx . SetCellValue ( "Sheet4" , "F1" , "Hello" )
2019-03-23 20:08:06 +08:00
val , err := xlsx . GetCellValue ( "Sheet1" , "F1" )
assert . NoError ( t , err )
assert . NotEqual ( t , "Hello" , val )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestCopySheet.xlsx" ) ) )
2018-12-27 18:51:44 +08:00
}
func TestCopySheetError ( t * testing . T ) {
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-08-19 13:37:15 +08:00
}
2018-12-27 18:51:44 +08:00
err = xlsx . CopySheet ( 0 , - 1 )
if ! assert . EqualError ( t , err , "invalid worksheet index" ) {
t . FailNow ( )
2017-04-04 19:12:35 +08:00
}
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestCopySheetError.xlsx" ) ) )
2017-04-04 19:12:35 +08:00
}
2017-04-23 00:10:23 +08:00
2017-04-28 15:49:41 +08:00
func TestAddTable ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-28 15:49:41 +08:00
}
2018-12-27 18:51:44 +08:00
2018-05-27 11:25:55 +08:00
err = xlsx . AddTable ( "Sheet1" , "B26" , "A21" , ` { } ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-05-27 11:25:55 +08:00
}
2018-12-27 18:51:44 +08:00
2018-05-27 11:25:55 +08:00
err = xlsx . AddTable ( "Sheet2" , "A2" , "B5" , ` { "table_name":"table","table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-05-27 11:25:55 +08:00
}
2018-12-27 18:51:44 +08:00
2018-05-27 11:25:55 +08:00
err = xlsx . AddTable ( "Sheet2" , "F1" , "F1" , ` { "table_style":"TableStyleMedium8"} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-28 15:49:41 +08:00
}
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestAddTable.xlsx" ) ) )
2017-04-28 15:49:41 +08:00
}
2017-04-30 20:03:43 +08:00
func TestAddShape ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-30 20:03:43 +08:00
}
2018-12-27 18:51:44 +08:00
2017-06-19 11:18:58 +08:00
xlsx . AddShape ( "Sheet1" , "A30" , ` { "type":"rect","paragraph":[ { "text":"Rectangle","font": { "color":"CD5C5C"}}, { "text":"Shape","font": { "bold":true,"color":"2980B9"}}]} ` )
xlsx . AddShape ( "Sheet1" , "B30" , ` { "type":"rect","paragraph":[ { "text":"Rectangle"}, { }]} ` )
xlsx . AddShape ( "Sheet1" , "C30" , ` { "type":"rect","paragraph":[]} ` )
xlsx . AddShape ( "Sheet3" , "H1" , ` { "type":"ellipseRibbon", "color": { "line":"#4286f4","fill":"#8eb9ff"}, "paragraph":[ { "font": { "bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}], "height": 90} ` )
2018-05-27 11:25:55 +08:00
xlsx . AddShape ( "Sheet3" , "H1" , "" )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestAddShape.xlsx" ) ) )
2017-04-30 20:03:43 +08:00
}
2017-05-13 13:28:21 +08:00
func TestAddComments ( t * testing . T ) {
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-05-13 13:28:21 +08:00
}
2018-12-27 18:51:44 +08:00
2017-09-11 15:53:25 +08:00
s := strings . Repeat ( "c" , 32768 )
2017-05-13 14:12:43 +08:00
xlsx . AddComment ( "Sheet1" , "A30" , ` { "author":" ` + s + ` ","text":" ` + s + ` "} ` )
xlsx . AddComment ( "Sheet2" , "B7" , ` { "author":"Excelize: ","text":"This is a comment."} ` )
2018-06-30 18:55:14 +08:00
2018-12-27 22:28:28 +08:00
if assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestAddComments.xlsx" ) ) ) {
2018-12-27 18:51:44 +08:00
assert . Len ( t , xlsx . GetComments ( ) , 2 )
}
2017-05-13 13:28:21 +08:00
}
2017-06-08 11:11:11 +08:00
func TestAutoFilter ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
outFile := filepath . Join ( "test" , "TestAutoFilter%d.xlsx" )
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-06-08 11:11:11 +08:00
}
2018-12-27 18:51:44 +08:00
formats := [ ] string {
` ` ,
2018-05-11 10:14:18 +08:00
` { "column":"B","expression":"x != blanks"} ` ,
` { "column":"B","expression":"x == blanks"} ` ,
` { "column":"B","expression":"x != nonblanks"} ` ,
` { "column":"B","expression":"x == nonblanks"} ` ,
` { "column":"B","expression":"x <= 1 and x >= 2"} ` ,
` { "column":"B","expression":"x == 1 or x == 2"} ` ,
` { "column":"B","expression":"x == 1 or x == 2*"} ` ,
2018-12-27 18:51:44 +08:00
}
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 ) {
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( fmt . Sprintf ( outFile , i + 1 ) ) )
2018-12-27 18:51:44 +08:00
}
} )
}
}
func TestAutoFilterError ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
outFile := filepath . Join ( "test" , "TestAutoFilterError%d.xlsx" )
2018-12-27 18:51:44 +08:00
xlsx , err := prepareTestBook1 ( )
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
formats := [ ] string {
2018-05-11 10:14:18 +08:00
` { "column":"B","expression":"x <= 1 and x >= blanks"} ` ,
` { "column":"B","expression":"x -- y or x == *2*"} ` ,
` { "column":"B","expression":"x != y or x ? *2"} ` ,
` { "column":"B","expression":"x -- y o r x == *2"} ` ,
` { "column":"B","expression":"x -- y"} ` ,
` { "column":"A","expression":"x -- y"} ` ,
}
2018-12-27 18:51:44 +08:00
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 . Error ( t , err ) {
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( fmt . Sprintf ( outFile , i + 1 ) ) )
2018-12-27 18:51:44 +08:00
}
} )
2017-06-08 11:11:11 +08:00
}
}
2017-04-23 00:10:23 +08:00
func TestAddChart ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-04-23 00:10:23 +08:00
}
2018-12-27 18:51:44 +08:00
2017-04-23 00:39:14 +08:00
categories := map [ string ] string { "A30" : "Small" , "A31" : "Normal" , "A32" : "Large" , "B29" : "Apple" , "C29" : "Orange" , "D29" : "Pear" }
values := map [ string ] int { "B30" : 2 , "C30" : 3 , "D30" : 3 , "B31" : 5 , "C31" : 2 , "D31" : 4 , "B32" : 6 , "C32" : 7 , "D32" : 8 }
for k , v := range categories {
xlsx . SetCellValue ( "Sheet1" , k , v )
}
for k , v := range values {
xlsx . SetCellValue ( "Sheet1" , k , v )
}
2018-05-27 11:25:55 +08:00
xlsx . AddChart ( "Sheet1" , "P1" , "" )
2018-03-05 21:23:52 +08:00
xlsx . AddChart ( "Sheet1" , "P1" , ` { "type":"col","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 2D Column Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet1" , "X1" , ` { "type":"colStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 2D Stacked Column Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet1" , "P16" , ` { "type":"colPercentStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 100% Stacked Column Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet1" , "X16" , ` { "type":"col3DClustered","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"bottom","show_legend_key":false},"title": { "name":"Fruit 3D Clustered Column Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet1" , "P30" , ` { "type":"col3DStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 3D 100% Stacked Bar Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet1" , "X30" , ` { "type":"col3DPercentStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 3D 100% Stacked Column Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet1" , "P45" , ` { "type":"col3D","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 3D Column Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
2018-02-12 11:45:42 +08:00
xlsx . AddChart ( "Sheet2" , "P1" , ` { "type":"radar","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"top_right","show_legend_key":false},"title": { "name":"Fruit Radar Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"span"} ` )
xlsx . AddChart ( "Sheet2" , "X1" , ` { "type":"scatter","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"bottom","show_legend_key":false},"title": { "name":"Fruit Scatter Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
2018-03-05 21:23:52 +08:00
xlsx . AddChart ( "Sheet2" , "P16" , ` { "type":"doughnut","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"right","show_legend_key":false},"title": { "name":"Fruit Doughnut Chart"},"plotarea": { "show_bubble_size":false,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet2" , "X16" , ` { "type":"line","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"top","show_legend_key":false},"title": { "name":"Fruit Line Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet2" , "P32" , ` { "type":"pie3D","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"bottom","show_legend_key":false},"title": { "name":"Fruit 3D Pie Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet2" , "X32" , ` { "type":"pie","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"bottom","show_legend_key":false},"title": { "name":"Fruit Pie Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"gap"} ` )
xlsx . AddChart ( "Sheet2" , "P48" , ` { "type":"bar","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 2D Clustered Bar Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet2" , "X48" , ` { "type":"barStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 2D Stacked Bar Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
2018-04-23 00:14:58 +08:00
xlsx . AddChart ( "Sheet2" , "P64" , ` { "type":"barPercentStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 2D Stacked 100% Bar Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
2018-03-05 21:23:52 +08:00
xlsx . AddChart ( "Sheet2" , "X64" , ` { "type":"bar3DClustered","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 3D Clustered Bar Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
2018-03-29 20:17:07 +08:00
xlsx . AddChart ( "Sheet2" , "P80" , ` { "type":"bar3DStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 3D Stacked Bar Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","y_axis": { "maximum":7.5,"minimum":0.5}} ` )
xlsx . AddChart ( "Sheet2" , "X80" , ` { "type":"bar3DPercentStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 3D 100% Stacked Bar Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","x_axis": { "reverse_order":true,"maximum":0,"minimum":0},"y_axis": { "reverse_order":true,"maximum":0,"minimum":0}} ` )
2018-12-23 00:07:47 +08:00
// area series charts
xlsx . AddChart ( "Sheet2" , "AF1" , ` { "type":"area","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 2D Area Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet2" , "AN1" , ` { "type":"areaStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 2D Stacked Area Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet2" , "AF16" , ` { "type":"areaPercentStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 2D 100% Stacked Area Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet2" , "AN16" , ` { "type":"area3D","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 3D Area Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet2" , "AF32" , ` { "type":"area3DStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 3D Stacked Area Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
xlsx . AddChart ( "Sheet2" , "AN32" , ` { "type":"area3DPercentStacked","series":[ { "name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}, { "name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"}, { "name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format": { "x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend": { "position":"left","show_legend_key":false},"title": { "name":"Fruit 3D 100% Stacked Area Chart"},"plotarea": { "show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"} ` )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestAddChart.xlsx" ) ) )
2017-07-24 10:26:02 +08:00
}
func TestInsertCol ( t * testing . T ) {
xlsx := NewFile ( )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
sheet1 := xlsx . GetSheetName ( 1 )
fillCells ( xlsx , sheet1 , 10 , 10 )
xlsx . SetCellHyperLink ( sheet1 , "A5" , "https://github.com/360EntSecGroup-Skylar/excelize" , "External" )
xlsx . MergeCell ( sheet1 , "A1" , "C3" )
err := xlsx . AutoFilter ( sheet1 , "A2" , "B2" , ` { "column":"B","expression":"x != blanks"} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-07-24 10:26:02 +08:00
}
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . InsertCol ( sheet1 , "A" ) )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestInsertCol.xlsx" ) ) )
2017-07-24 10:26:02 +08:00
}
func TestRemoveCol ( t * testing . T ) {
xlsx := NewFile ( )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
sheet1 := xlsx . GetSheetName ( 1 )
fillCells ( xlsx , sheet1 , 10 , 15 )
xlsx . SetCellHyperLink ( sheet1 , "A5" , "https://github.com/360EntSecGroup-Skylar/excelize" , "External" )
xlsx . SetCellHyperLink ( sheet1 , "C5" , "https://github.com" , "External" )
xlsx . MergeCell ( sheet1 , "A1" , "B1" )
xlsx . MergeCell ( sheet1 , "A2" , "B2" )
2019-03-23 20:08:06 +08:00
assert . NoError ( t , xlsx . RemoveCol ( sheet1 , "A" ) )
assert . NoError ( t , xlsx . RemoveCol ( sheet1 , "A" ) )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestRemoveCol.xlsx" ) ) )
2017-07-24 10:26:02 +08:00
}
2017-07-30 12:40:59 +08:00
func TestSetPane ( t * testing . T ) {
xlsx := NewFile ( )
xlsx . SetPanes ( "Sheet1" , ` { "freeze":false,"split":false} ` )
2017-09-13 22:00:33 +08:00
xlsx . NewSheet ( "Panes 2" )
xlsx . SetPanes ( "Panes 2" , ` { "freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[ { "sqref":"K16","active_cell":"K16","pane":"topRight"}]} ` )
xlsx . NewSheet ( "Panes 3" )
xlsx . SetPanes ( "Panes 3" , ` { "freeze":false,"split":true,"x_split":3270,"y_split":1800,"top_left_cell":"N57","active_pane":"bottomLeft","panes":[ { "sqref":"I36","active_cell":"I36"}, { "sqref":"G33","active_cell":"G33","pane":"topRight"}, { "sqref":"J60","active_cell":"J60","pane":"bottomLeft"}, { "sqref":"O60","active_cell":"O60","pane":"bottomRight"}]} ` )
xlsx . NewSheet ( "Panes 4" )
xlsx . SetPanes ( "Panes 4" , ` { "freeze":true,"split":false,"x_split":0,"y_split":9,"top_left_cell":"A34","active_pane":"bottomLeft","panes":[ { "sqref":"A11:XFD11","active_cell":"A11","pane":"bottomLeft"}]} ` )
2018-05-27 11:25:55 +08:00
xlsx . SetPanes ( "Panes 4" , "" )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetPane.xlsx" ) ) )
2017-07-30 12:40:59 +08:00
}
2017-08-11 23:15:33 +08:00
func TestConditionalFormat ( t * testing . T ) {
xlsx := NewFile ( )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
sheet1 := xlsx . GetSheetName ( 1 )
fillCells ( xlsx , sheet1 , 10 , 15 )
2017-08-11 23:15:33 +08:00
var format1 , format2 , format3 int
var err error
// Rose format for bad conditional.
format1 , err = xlsx . NewConditionalStyle ( ` { "font": { "color":"#9A0511"},"fill": { "type":"pattern","color":["#FEC7CE"],"pattern":1}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2017-08-11 23:15:33 +08:00
// Light yellow format for neutral conditional.
format2 , err = xlsx . NewConditionalStyle ( ` { "fill": { "type":"pattern","color":["#FEEAA0"],"pattern":1}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2017-08-11 23:15:33 +08:00
// Light green format for good conditional.
format3 , err = xlsx . NewConditionalStyle ( ` { "font": { "color":"#09600B"},"fill": { "type":"pattern","color":["#C7EECF"],"pattern":1}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2017-08-11 23:15:33 +08:00
// Color scales: 2 color.
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "A1:A10" , ` [ { "type":"2_color_scale","criteria":"=","min_type":"min","max_type":"max","min_color":"#F8696B","max_color":"#63BE7B"}] ` )
2017-08-11 23:15:33 +08:00
// Color scales: 3 color.
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "B1:B10" , ` [ { "type":"3_color_scale","criteria":"=","min_type":"min","mid_type":"percentile","max_type":"max","min_color":"#F8696B","mid_color":"#FFEB84","max_color":"#63BE7B"}] ` )
2017-08-11 23:15:33 +08:00
// Hightlight cells rules: between...
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "C1:C10" , fmt . Sprintf ( ` [ { "type":"cell","criteria":"between","format":%d,"minimum":"6","maximum":"8"}] ` , format1 ) )
2017-08-11 23:15:33 +08:00
// Hightlight cells rules: Greater Than...
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "D1:D10" , fmt . Sprintf ( ` [ { "type":"cell","criteria":">","format":%d,"value":"6"}] ` , format3 ) )
2017-08-11 23:15:33 +08:00
// Hightlight cells rules: Equal To...
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "E1:E10" , fmt . Sprintf ( ` [ { "type":"top","criteria":"=","format":%d}] ` , format3 ) )
2017-08-11 23:15:33 +08:00
// Hightlight cells rules: Not Equal To...
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "F1:F10" , fmt . Sprintf ( ` [ { "type":"unique","criteria":"=","format":%d}] ` , format2 ) )
2017-08-11 23:15:33 +08:00
// Hightlight cells rules: Duplicate Values...
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "G1:G10" , fmt . Sprintf ( ` [ { "type":"duplicate","criteria":"=","format":%d}] ` , format2 ) )
2017-08-11 23:15:33 +08:00
// Top/Bottom rules: Top 10%.
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "H1:H10" , fmt . Sprintf ( ` [ { "type":"top","criteria":"=","format":%d,"value":"6","percent":true}] ` , format1 ) )
2017-08-11 23:15:33 +08:00
// Top/Bottom rules: Above Average...
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "I1:I10" , fmt . Sprintf ( ` [ { "type":"average","criteria":"=","format":%d, "above_average": true}] ` , format3 ) )
2017-08-11 23:15:33 +08:00
// Top/Bottom rules: Below Average...
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "J1:J10" , fmt . Sprintf ( ` [ { "type":"average","criteria":"=","format":%d, "above_average": false}] ` , format1 ) )
2017-08-11 23:15:33 +08:00
// Data Bars: Gradient Fill.
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "K1:K10" , ` [ { "type":"data_bar", "criteria":"=", "min_type":"min","max_type":"max","bar_color":"#638EC6"}] ` )
2017-08-18 20:55:27 +08:00
// Use a formula to determine which cells to format.
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "L1:L10" , fmt . Sprintf ( ` [ { "type":"formula", "criteria":"L2<3", "format":%d}] ` , format1 ) )
2018-05-27 11:25:55 +08:00
// Test set invalid format set in conditional format
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "L1:L10" , "" )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
err = xlsx . SaveAs ( filepath . Join ( "test" , "TestConditionalFormat.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2017-08-11 23:15:33 +08:00
}
// Set conditional format with illegal valid type.
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "K1:K10" , ` [ { "type":"", "criteria":"=", "min_type":"min","max_type":"max","bar_color":"#638EC6"}] ` )
2017-08-11 23:15:33 +08:00
// Set conditional format with illegal criteria type.
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetConditionalFormat ( sheet1 , "K1:K10" , ` [ { "type":"data_bar", "criteria":"", "min_type":"min","max_type":"max","bar_color":"#638EC6"}] ` )
2018-12-27 18:51:44 +08:00
// Set conditional format with file without dxfs element shold not return error.
2018-12-27 22:28:28 +08:00
xlsx , err = OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2017-08-11 23:15:33 +08:00
_ , err = xlsx . NewConditionalStyle ( ` { "font": { "color":"#9A0511"},"fill": { "type":"pattern","color":["#FEC7CE"],"pattern":1}} ` )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
}
2017-08-11 23:15:33 +08:00
}
2017-09-06 13:15:25 +08:00
2018-12-27 18:51:44 +08:00
func TestConditionalFormatError ( t * testing . T ) {
xlsx := NewFile ( )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
sheet1 := xlsx . GetSheetName ( 1 )
fillCells ( xlsx , sheet1 , 10 , 15 )
2018-12-27 18:51:44 +08:00
// Set conditional format with illegal JSON string should return error
_ , err := xlsx . NewConditionalStyle ( "" )
if ! assert . EqualError ( t , err , "unexpected end of JSON input" ) {
t . FailNow ( )
2017-09-06 13:15:25 +08:00
}
}
2018-03-02 10:19:40 +08:00
func TestSharedStrings ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "SharedStrings.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-03-02 10:19:40 +08:00
}
xlsx . GetRows ( "Sheet1" )
}
2018-03-12 20:14:39 +08:00
func TestSetSheetRow ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-03-12 20:14:39 +08:00
}
2018-12-27 18:51:44 +08:00
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetSheetRow ( "Sheet1" , "B27" , & [ ] interface { } { "cell" , nil , int32 ( 42 ) , float64 ( 42 ) , time . Now ( ) . UTC ( ) } )
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetSheetRow ( "Sheet1" , "" , & [ ] interface { } { "cell" , nil , 2 } ) ,
` cannot convert cell "" to coordinates: invalid cell name "" ` )
2018-12-27 18:51:44 +08:00
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetSheetRow ( "Sheet1" , "B27" , [ ] interface { } { } ) , ` pointer to slice expected ` )
assert . EqualError ( t , xlsx . SetSheetRow ( "Sheet1" , "B27" , & xlsx ) , ` pointer to slice expected ` )
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestSetSheetRow.xlsx" ) ) )
2018-03-12 20:14:39 +08:00
}
2018-05-07 16:14:35 +08:00
2018-05-11 10:14:18 +08:00
func TestOutlineLevel ( t * testing . T ) {
xlsx := NewFile ( )
xlsx . NewSheet ( "Sheet2" )
xlsx . SetColOutlineLevel ( "Sheet1" , "D" , 4 )
xlsx . GetColOutlineLevel ( "Sheet1" , "D" )
xlsx . GetColOutlineLevel ( "Shee2" , "A" )
xlsx . SetColWidth ( "Sheet2" , "A" , "D" , 13 )
xlsx . SetColOutlineLevel ( "Sheet2" , "B" , 2 )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetRowOutlineLevel ( "Sheet1" , 2 , 250 )
2019-03-23 20:08:06 +08:00
assert . EqualError ( t , xlsx . SetRowOutlineLevel ( "Sheet1" , 0 , 1 ) , "invalid row number 0" )
level , err := xlsx . GetRowOutlineLevel ( "Sheet1" , 2 )
assert . NoError ( t , err )
assert . Equal ( t , uint8 ( 250 ) , level )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2019-03-23 20:08:06 +08:00
_ , err = xlsx . GetRowOutlineLevel ( "Sheet1" , 0 )
assert . EqualError ( t , err , ` invalid row number 0 ` )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
2019-03-23 20:08:06 +08:00
err = xlsx . SaveAs ( filepath . Join ( "test" , "TestOutlineLevel.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-05-11 10:14:18 +08:00
}
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
xlsx , err = OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-05-11 10:14:18 +08:00
}
xlsx . SetColOutlineLevel ( "Sheet2" , "B" , 2 )
}
2018-07-07 15:59:48 +08:00
func TestThemeColor ( t * testing . T ) {
t . Log ( ThemeColor ( "000000" , - 0.1 ) )
t . Log ( ThemeColor ( "000000" , 0 ) )
t . Log ( ThemeColor ( "000000" , 1 ) )
}
func TestHSL ( t * testing . T ) {
var hsl HSL
t . Log ( hsl . RGBA ( ) )
t . Log ( hslModel ( hsl ) )
t . Log ( hslModel ( color . Gray16 { Y : uint16 ( 1 ) } ) )
t . Log ( HSLToRGB ( 0 , 1 , 0.4 ) )
t . Log ( HSLToRGB ( 0 , 1 , 0.6 ) )
t . Log ( hueToRGB ( 0 , 0 , - 1 ) )
t . Log ( hueToRGB ( 0 , 0 , 2 ) )
t . Log ( hueToRGB ( 0 , 0 , 1.0 / 7 ) )
t . Log ( hueToRGB ( 0 , 0 , 0.4 ) )
t . Log ( hueToRGB ( 0 , 0 , 2.0 / 4 ) )
t . Log ( RGBToHSL ( 255 , 255 , 0 ) )
t . Log ( RGBToHSL ( 0 , 255 , 255 ) )
t . Log ( RGBToHSL ( 250 , 100 , 50 ) )
t . Log ( RGBToHSL ( 50 , 100 , 250 ) )
t . Log ( RGBToHSL ( 250 , 50 , 100 ) )
}
2018-10-27 22:54:17 +08:00
func TestSearchSheet ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "SharedStrings.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-10-27 22:54:17 +08:00
}
2018-12-27 18:51:44 +08:00
2018-10-27 22:54:17 +08:00
// Test search in a not exists worksheet.
t . Log ( xlsx . SearchSheet ( "Sheet4" , "" ) )
// Test search a not exists value.
t . Log ( xlsx . SearchSheet ( "Sheet1" , "X" ) )
t . Log ( xlsx . SearchSheet ( "Sheet1" , "A" ) )
2018-12-26 14:48:14 +08:00
// Test search the coordinates where the numerical value in the range of
// "0-9" of Sheet1 is described by regular expression:
t . Log ( xlsx . SearchSheet ( "Sheet1" , "[0-9]" , true ) )
2018-12-26 13:30:59 +08:00
}
2018-11-02 23:08:31 +08:00
func TestProtectSheet ( t * testing . T ) {
xlsx := NewFile ( )
xlsx . ProtectSheet ( "Sheet1" , nil )
xlsx . ProtectSheet ( "Sheet1" , & FormatSheetProtection {
Password : "password" ,
EditScenarios : false ,
} )
2018-12-27 18:51:44 +08:00
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestProtectSheet.xlsx" ) ) )
2018-11-02 23:08:31 +08:00
}
2018-11-04 23:14:43 +08:00
func TestUnprotectSheet ( t * testing . T ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if ! assert . NoError ( t , err ) {
t . FailNow ( )
2018-11-04 23:14:43 +08:00
}
2018-12-27 18:51:44 +08:00
2018-11-04 23:14:43 +08:00
xlsx . UnprotectSheet ( "Sheet1" )
2018-12-27 22:28:28 +08:00
assert . NoError ( t , xlsx . SaveAs ( filepath . Join ( "test" , "TestUnprotectSheet.xlsx" ) ) )
2018-11-04 23:14:43 +08:00
}
2018-12-27 18:51:44 +08:00
func prepareTestBook1 ( ) ( * File , error ) {
2018-12-27 22:28:28 +08:00
xlsx , err := OpenFile ( filepath . Join ( "test" , "Book1.xlsx" ) )
2018-12-27 18:51:44 +08:00
if err != nil {
return nil , err
}
2018-12-27 22:28:28 +08:00
err = xlsx . AddPicture ( "Sheet2" , "I9" , filepath . Join ( "test" , "images" , "excel.jpg" ) ,
2018-12-27 18:51:44 +08:00
` { "x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"} ` )
if err != nil {
return nil , err
}
// Test add picture to worksheet with offset, external hyperlink and positioning.
2018-12-27 22:28:28 +08:00
err = xlsx . AddPicture ( "Sheet1" , "F21" , filepath . Join ( "test" , "images" , "excel.png" ) ,
2018-12-27 18:51:44 +08:00
` { "x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"} ` )
if err != nil {
return nil , err
}
2018-12-27 22:28:28 +08:00
file , err := ioutil . ReadFile ( filepath . Join ( "test" , "images" , "excel.jpg" ) )
2018-12-27 18:51:44 +08:00
if err != nil {
return nil , err
}
err = xlsx . AddPictureFromBytes ( "Sheet1" , "Q1" , "" , "Excel Logo" , ".jpg" , file )
if err != nil {
return nil , err
}
return xlsx , nil
}
func prepareTestBook3 ( ) ( * File , error ) {
xlsx := NewFile ( )
xlsx . NewSheet ( "Sheet1" )
xlsx . NewSheet ( "XLSXSheet2" )
xlsx . NewSheet ( "XLSXSheet3" )
xlsx . SetCellInt ( "XLSXSheet2" , "A23" , 56 )
xlsx . SetCellStr ( "Sheet1" , "B20" , "42" )
xlsx . SetActiveSheet ( 0 )
2018-12-27 22:28:28 +08:00
err := xlsx . AddPicture ( "Sheet1" , "H2" , filepath . Join ( "test" , "images" , "excel.gif" ) ,
` { "x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"} ` )
2018-12-27 18:51:44 +08:00
if err != nil {
return nil , err
}
2018-12-27 22:28:28 +08:00
err = xlsx . AddPicture ( "Sheet1" , "C2" , filepath . Join ( "test" , "images" , "excel.png" ) , "" )
2018-12-27 18:51:44 +08:00
if err != nil {
return nil , err
}
return xlsx , nil
}
func prepareTestBook4 ( ) ( * File , error ) {
xlsx := NewFile ( )
xlsx . SetColWidth ( "Sheet1" , "B" , "A" , 12 )
xlsx . SetColWidth ( "Sheet1" , "A" , "B" , 12 )
xlsx . GetColWidth ( "Sheet1" , "A" )
xlsx . GetColWidth ( "Sheet1" , "C" )
return xlsx , nil
}
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
func fillCells ( xlsx * File , sheet string , colCount , rowCount int ) {
for col := 1 ; col <= colCount ; col ++ {
for row := 1 ; row <= rowCount ; row ++ {
2019-03-23 20:08:06 +08:00
cell , _ := CoordinatesToCellName ( col , row )
Huge refactorig for consistent col/row numbering (#356)
* Huge refactorig for consistent col/row numbering
Started from simply changing ToALphaString()/TitleToNumber() logic and related fixes.
But have to go deeper, do fixes, after do related fixes and again and again.
Major improvements:
1. Tests made stronger again (But still be weak).
2. "Empty" returns for incorrect input replaces with panic.
3. Check for correct col/row/cell naming & addressing by default.
4. Removed huge amount of duplicated code.
5. Removed ToALphaString(), TitleToNumber() and it helpers functions at all,
and replaced with SplitCellName(), JoinCellName(), ColumnNameToNumber(), ColumnNumberToName(), CellNameToCoordinates(), CoordinatesToCellName().
6. Minor fixes for internal variable naming for code readability (ex. col, row for input params, colIdx, rowIdx for slice indexes etc).
* Formatting fixes
2019-03-20 00:14:41 +08:00
xlsx . SetCellStr ( sheet , cell , cell )
}
}
}