diff options
| -rw-r--r-- | .travis.yml | 2 | ||||
| -rw-r--r-- | CONTRIBUTING.md | 6 | ||||
| -rw-r--r-- | col.go | 125 | ||||
| -rw-r--r-- | col_test.go | 4 | ||||
| -rw-r--r-- | merge.go | 25 | ||||
| -rw-r--r-- | picture.go | 4 | ||||
| -rw-r--r-- | sheet.go | 4 | ||||
| -rw-r--r-- | table.go | 6 | ||||
| -rw-r--r-- | xmlWorksheet.go | 8 | 
9 files changed, 117 insertions, 67 deletions
diff --git a/.travis.yml b/.travis.yml index 5012f86..1cb1d49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ os:    - osx  env: -  matrix: +  jobs:      - GOARCH=amd64      - GOARCH=386 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index afb7d4e..53c650e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -234,7 +234,9 @@ By making a contribution to this project, I certify that:  Then you just add a line to every git commit message: -    Signed-off-by: Ri Xu https://xuri.me +```text +Signed-off-by: Ri Xu https://xuri.me +```  Use your real name (sorry, no pseudonyms or anonymous contributions.) @@ -460,4 +462,4 @@ Do not use package math/rand to generate keys, even  throwaway ones. Unseeded, the generator is completely predictable.  Seeded with time.Nanoseconds(), there are just a few bits of entropy.  Instead, use crypto/rand's Reader, and if you need text, print to -hexadecimal or base64 +hexadecimal or base64. @@ -13,6 +13,8 @@ import (  	"errors"  	"math"  	"strings" + +	"github.com/mohae/deepcopy"  )  // Define the default cell size and EMU unit of measurement. @@ -59,7 +61,7 @@ func (f *File) GetColVisible(sheet, col string) (bool, error) {  //  //    err := f.SetColVisible("Sheet1", "D", false)  // -//    Hide the columns from D to F (included) +// Hide the columns from D to F (included):  //  //    err := f.SetColVisible("Sheet1", "D:F", false)  // @@ -87,23 +89,31 @@ func (f *File) SetColVisible(sheet, columns string, visible bool) error {  		return err  	}  	colData := xlsxCol{ -		Min:		min, -		Max:		max, -		Width:		9, // default width -		Hidden:		!visible, +		Min:         min, +		Max:         max, +		Width:       9, // default width +		Hidden:      !visible,  		CustomWidth: true,  	} -	if xlsx.Cols != nil { -		xlsx.Cols.Col = append(xlsx.Cols.Col, colData) -	} else { +	if xlsx.Cols == nil {  		cols := xlsxCols{}  		cols.Col = append(cols.Col, colData)  		xlsx.Cols = &cols -	} +		return nil +	} +	xlsx.Cols.Col = flatCols(colData, xlsx.Cols.Col, func(fc, c xlsxCol) xlsxCol { +		fc.BestFit = c.BestFit +		fc.Collapsed = c.Collapsed +		fc.CustomWidth = c.CustomWidth +		fc.OutlineLevel = c.OutlineLevel +		fc.Phonetic = c.Phonetic +		fc.Style = c.Style +		fc.Width = c.Width +		return fc +	})  	return nil  } -  // GetColOutlineLevel provides a function to get outline level of a single  // column by given worksheet name and column name. For example, get outline  // level of column D in Sheet1: @@ -162,16 +172,16 @@ func (f *File) SetColOutlineLevel(sheet, col string, level uint8) error {  		xlsx.Cols = &cols  		return err  	} -	for v := range xlsx.Cols.Col { -		if xlsx.Cols.Col[v].Min <= colNum && colNum <= xlsx.Cols.Col[v].Max { -			colData = xlsx.Cols.Col[v] -		} -	} -	colData.Min = colNum -	colData.Max = colNum -	colData.OutlineLevel = level -	colData.CustomWidth = true -	xlsx.Cols.Col = append(xlsx.Cols.Col, colData) +	xlsx.Cols.Col = flatCols(colData, xlsx.Cols.Col, func(fc, c xlsxCol) xlsxCol { +		fc.BestFit = c.BestFit +		fc.Collapsed = c.Collapsed +		fc.CustomWidth = c.CustomWidth +		fc.Hidden = c.Hidden +		fc.Phonetic = c.Phonetic +		fc.Style = c.Style +		fc.Width = c.Width +		return fc +	})  	return err  } @@ -214,21 +224,21 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {  	if xlsx.Cols == nil {  		xlsx.Cols = &xlsxCols{}  	} -	var find bool -	for idx, col := range xlsx.Cols.Col { -		if col.Min == min && col.Max == max { -			xlsx.Cols.Col[idx].Style = styleID -			find = true -		} -	} -	if !find { -		xlsx.Cols.Col = append(xlsx.Cols.Col, xlsxCol{ -			Min:   min, -			Max:   max, -			Width: 9, -			Style: styleID, -		}) -	} +	xlsx.Cols.Col = flatCols(xlsxCol{ +		Min:   min, +		Max:   max, +		Width: 9, +		Style: styleID, +	}, xlsx.Cols.Col, func(fc, c xlsxCol) xlsxCol { +		fc.BestFit = c.BestFit +		fc.Collapsed = c.Collapsed +		fc.CustomWidth = c.CustomWidth +		fc.Hidden = c.Hidden +		fc.OutlineLevel = c.OutlineLevel +		fc.Phonetic = c.Phonetic +		fc.Width = c.Width +		return fc +	})  	return nil  } @@ -261,16 +271,55 @@ func (f *File) SetColWidth(sheet, startcol, endcol string, width float64) error  		Width:       width,  		CustomWidth: true,  	} -	if xlsx.Cols != nil { -		xlsx.Cols.Col = append(xlsx.Cols.Col, col) -	} else { +	if xlsx.Cols == nil {  		cols := xlsxCols{}  		cols.Col = append(cols.Col, col)  		xlsx.Cols = &cols +		return err  	} +	xlsx.Cols.Col = flatCols(col, xlsx.Cols.Col, func(fc, c xlsxCol) xlsxCol { +		fc.BestFit = c.BestFit +		fc.Collapsed = c.Collapsed +		fc.Hidden = c.Hidden +		fc.OutlineLevel = c.OutlineLevel +		fc.Phonetic = c.Phonetic +		fc.Style = c.Style +		return fc +	})  	return err  } +// flatCols provides a method for the column's operation functions to flatten +// and check the worksheet columns. +func flatCols(col xlsxCol, cols []xlsxCol, replacer func(fc, c xlsxCol) xlsxCol) []xlsxCol { +	fc := []xlsxCol{} +	for i := col.Min; i <= col.Max; i++ { +		c := deepcopy.Copy(col).(xlsxCol) +		c.Min, c.Max = i, i +		fc = append(fc, c) +	} +	inFlat := func(colID int, cols []xlsxCol) (int, bool) { +		for idx, c := range cols { +			if c.Max == colID && c.Min == colID { +				return idx, true +			} +		} +		return -1, false +	} +	for _, column := range cols { +		for i := column.Min; i <= column.Max; i++ { +			if idx, ok := inFlat(i, fc); ok { +				fc[idx] = replacer(fc[idx], column) +				continue +			} +			c := deepcopy.Copy(column).(xlsxCol) +			c.Min, c.Max = i, i +			fc = append(fc, c) +		} +	} +	return fc +} +  // positionObjectPixels calculate the vertices that define the position of a  // graphical object within the worksheet in pixels.  // diff --git a/col_test.go b/col_test.go index 08fac1c..050c998 100644 --- a/col_test.go +++ b/col_test.go @@ -31,7 +31,7 @@ func TestColumnVisibility(t *testing.T) {  		assert.Equal(t, false, visible)  		assert.NoError(t, err)  		// ...and displaying them back SetColVisible(...true) -		assert.NoError(t, f.SetColVisible("Sheet1", "F:V", true)) +		assert.NoError(t, f.SetColVisible("Sheet1", "V:F", true))  		visible, err = f.GetColVisible("Sheet1", "F")  		assert.Equal(t, true, visible)  		assert.NoError(t, err) @@ -53,7 +53,7 @@ func TestColumnVisibility(t *testing.T) {  		f.NewSheet("Sheet3")  		assert.NoError(t, f.SetColVisible("Sheet3", "E", false)) - +		assert.EqualError(t, f.SetColVisible("Sheet1", "A:-1", true), "invalid column name \"-1\"")  		assert.EqualError(t, f.SetColVisible("SheetN", "E", false), "sheet SheetN is not exist")  		assert.NoError(t, f.SaveAs(filepath.Join("test", "TestColumnVisibility.xlsx")))  	}) @@ -22,20 +22,17 @@ import (  // If you create a merged cell that overlaps with another existing merged cell,  // those merged cells that already exist will be removed.  // -//                 B1(x1,y1)              D1(x2,y1) -//                +--------------------------------+ -//                |                                | -//                |                                | -//     A4(x3,y3)  |        C4(x4,y3)               | -//    +-----------------------------+              | -//    |           |                 |              | -//    |           |                 |              | -//    |           |B5(x1,y2)        |     D5(x2,y2)| -//    |           +--------------------------------+ -//    |                             | -//    |                             | -//    |A8(x3,y4)           C8(x4,y4)| -//    +-----------------------------+ +//                 B1(x1,y1)      D1(x2,y1) +//               +------------------------+ +//               |                        | +//     A4(x3,y3) |    C4(x4,y3)           | +//    +------------------------+          | +//    |          |             |          | +//    |          |B5(x1,y2)    | D5(x2,y2)| +//    |          +------------------------+ +//    |                        | +//    |A8(x3,y4)      C8(x4,y4)| +//    +------------------------+  //  func (f *File) MergeCell(sheet, hcell, vcell string) error {  	rect1, err := f.areaRefToCoordinates(hcell + ":" + vcell) @@ -462,8 +462,8 @@ func (f *File) GetPicture(sheet, cell string) (string, []byte, error) {  	return f.getPicture(row, col, drawingXML, drawingRelationships)  } -// DeletePicture provides a function to delete chart in XLSX by given -// worksheet and cell name. Note that the image file won't deleted from the +// DeletePicture provides a function to delete charts in XLSX by given +// worksheet and cell name. Note that the image file won't be deleted from the  // document currently.  func (f *File) DeletePicture(sheet, cell string) (err error) {  	col, row, err := CellNameToCoordinates(cell) @@ -287,8 +287,8 @@ func (f *File) GetActiveSheetIndex() int {  	return 0  } -// SetSheetName provides a function to set the worksheet name be given old and -// new worksheet name. Maximum 31 characters are allowed in sheet title and +// SetSheetName provides a function to set the worksheet name by given old and +// new worksheet names. Maximum 31 characters are allowed in sheet title and  // this function only changes the name of the sheet and will not update the  // sheet name in the formula or reference associated with the cell. So there  // may be problem formula error or reference missing. @@ -39,8 +39,10 @@ func parseFormatTableSet(formatSet string) (*formatTable, error) {  //  //    err := f.AddTable("Sheet2", "F2", "H6", `{"table_name":"table","table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)  // -// Note that the table at least two lines include string type header. Multiple -// tables coordinate areas can't have an intersection. +// Note that the table must be at least two lines including the header. The +// header cells must contain strings and must be unique, and must set the +// header row data of the table before calling the AddTable function. Multiple +// tables coordinate areas that can't have an intersection.  //  // table_name: The name of the table, in the same worksheet name of the table should be unique  // diff --git a/xmlWorksheet.go b/xmlWorksheet.go index ed304cc..46253e6 100644 --- a/xmlWorksheet.go +++ b/xmlWorksheet.go @@ -278,15 +278,15 @@ type xlsxCols struct {  // width and column formatting for one or more columns of the worksheet.  type xlsxCol struct {  	BestFit      bool    `xml:"bestFit,attr,omitempty"` -	Collapsed    bool    `xml:"collapsed,attr"` +	Collapsed    bool    `xml:"collapsed,attr,omitempty"`  	CustomWidth  bool    `xml:"customWidth,attr,omitempty"` -	Hidden       bool    `xml:"hidden,attr"` +	Hidden       bool    `xml:"hidden,attr,omitempty"`  	Max          int     `xml:"max,attr"`  	Min          int     `xml:"min,attr"`  	OutlineLevel uint8   `xml:"outlineLevel,attr,omitempty"`  	Phonetic     bool    `xml:"phonetic,attr,omitempty"` -	Style        int     `xml:"style,attr"` -	Width        float64 `xml:"width,attr"` +	Style        int     `xml:"style,attr,omitempty"` +	Width        float64 `xml:"width,attr,omitempty"`  }  // xlsxDimension directly maps the dimension element in the namespace  | 
