package xlsx
import (
"bytes"
"encoding/xml"
. "gopkg.in/check.v1"
)
type SheetSuite struct{}
var _ = Suite(&SheetSuite{})
// Test we can add a Row to a Sheet
func (s *SheetSuite) TestAddRow(c *C) {
var f *File
f = NewFile()
sheet := f.AddSheet("MySheet")
row := sheet.AddRow()
c.Assert(row, NotNil)
c.Assert(len(sheet.Rows), Equals, 1)
}
func (s *SheetSuite) TestMakeXLSXSheetFromRows(c *C) {
file := NewFile()
sheet := file.AddSheet("Sheet1")
row := sheet.AddRow()
cell := row.AddCell()
cell.Value = "A cell!"
refTable := NewSharedStringRefTable()
styles := newXlsxStyleSheet(nil)
xSheet := sheet.makeXLSXSheet(refTable, styles)
c.Assert(xSheet.Dimension.Ref, Equals, "A1")
c.Assert(xSheet.SheetData.Row, HasLen, 1)
xRow := xSheet.SheetData.Row[0]
c.Assert(xRow.R, Equals, 1)
c.Assert(xRow.Spans, Equals, "")
c.Assert(xRow.C, HasLen, 1)
xC := xRow.C[0]
c.Assert(xC.R, Equals, "A1")
c.Assert(xC.S, Equals, 0)
c.Assert(xC.T, Equals, "s") // Shared string type
c.Assert(xC.V, Equals, "0") // reference to shared string
xSST := refTable.makeXLSXSST()
c.Assert(xSST.Count, Equals, 1)
c.Assert(xSST.UniqueCount, Equals, 1)
c.Assert(xSST.SI, HasLen, 1)
xSI := xSST.SI[0]
c.Assert(xSI.T, Equals, "A cell!")
}
// Test if the NumFmts assigned properly according the FormatCode in cell.
func (s *SheetSuite) TestMakeXLSXSheetWithNumFormats(c *C) {
file := NewFile()
sheet := file.AddSheet("Sheet1")
row := sheet.AddRow()
cell1 := row.AddCell()
cell1.Value = "A cell!"
cell1.numFmt = "general"
cell2 := row.AddCell()
cell2.Value = "37947.7500001"
cell2.numFmt = "0"
cell3 := row.AddCell()
cell3.Value = "37947.7500001"
cell3.numFmt = "mm-dd-yy"
cell4 := row.AddCell()
cell4.Value = "37947.7500001"
cell4.numFmt = "hh:mm:ss"
refTable := NewSharedStringRefTable()
styles := newXlsxStyleSheet(nil)
worksheet := sheet.makeXLSXSheet(refTable, styles)
c.Assert(styles.CellStyleXfs.Count, Equals, 1)
// The 0th CellStyleXf could just be getting the zero values by default
c.Assert(styles.CellStyleXfs.Xf[0].FontId, Equals, 0)
c.Assert(styles.CellStyleXfs.Xf[0].FillId, Equals, 0)
c.Assert(styles.CellStyleXfs.Xf[0].BorderId, Equals, 0)
c.Assert(styles.CellXfs.Count, Equals, 4)
c.Assert(styles.CellXfs.Xf[0].NumFmtId, Equals, 0)
c.Assert(styles.CellXfs.Xf[1].NumFmtId, Equals, 1)
c.Assert(styles.CellXfs.Xf[2].NumFmtId, Equals, 14)
c.Assert(styles.CellXfs.Xf[3].NumFmtId, Equals, 164)
c.Assert(styles.NumFmts.Count, Equals, 1)
c.Assert(styles.NumFmts.NumFmt[0].NumFmtId, Equals, 164)
c.Assert(styles.NumFmts.NumFmt[0].FormatCode, Equals, "hh:mm:ss")
// Finally we check that the cell points to the right CellXf /
// CellStyleXf.
c.Assert(worksheet.SheetData.Row[0].C[0].S, Equals, 0)
c.Assert(worksheet.SheetData.Row[0].C[1].S, Equals, 1)
}
// When we create the xlsxSheet we also populate the xlsxStyles struct
// with style information.
func (s *SheetSuite) TestMakeXLSXSheetAlsoPopulatesXLSXSTyles(c *C) {
file := NewFile()
sheet := file.AddSheet("Sheet1")
row := sheet.AddRow()
cell1 := row.AddCell()
cell1.Value = "A cell!"
style1 := NewStyle()
style1.Font = *NewFont(10, "Verdana")
style1.Fill = *NewFill("solid", "FFFFFFFF", "00000000")
style1.Border = *NewBorder("none", "thin", "none", "thin")
cell1.SetStyle(style1)
// We need a second style to check that Xfs are populated correctly.
cell2 := row.AddCell()
cell2.Value = "Another cell!"
style2 := NewStyle()
style2.Font = *NewFont(10, "Verdana")
style2.Fill = *NewFill("solid", "FFFFFFFF", "00000000")
style2.Border = *NewBorder("none", "thin", "none", "thin")
cell2.SetStyle(style2)
refTable := NewSharedStringRefTable()
styles := newXlsxStyleSheet(nil)
worksheet := sheet.makeXLSXSheet(refTable, styles)
c.Assert(styles.Fonts.Count, Equals, 2)
c.Assert(styles.Fonts.Font[0].Sz.Val, Equals, "12")
c.Assert(styles.Fonts.Font[0].Name.Val, Equals, "Verdana")
c.Assert(styles.Fonts.Font[1].Sz.Val, Equals, "10")
c.Assert(styles.Fonts.Font[1].Name.Val, Equals, "Verdana")
c.Assert(styles.Fills.Count, Equals, 3)
c.Assert(styles.Fills.Fill[0].PatternFill.PatternType, Equals, "none")
c.Assert(styles.Fills.Fill[0].PatternFill.FgColor.RGB, Equals, "FFFFFFFF")
c.Assert(styles.Fills.Fill[0].PatternFill.BgColor.RGB, Equals, "00000000")
c.Assert(styles.Borders.Count, Equals, 2)
c.Assert(styles.Borders.Border[1].Left.Style, Equals, "none")
c.Assert(styles.Borders.Border[1].Right.Style, Equals, "thin")
c.Assert(styles.Borders.Border[1].Top.Style, Equals, "none")
c.Assert(styles.Borders.Border[1].Bottom.Style, Equals, "thin")
c.Assert(styles.CellStyleXfs.Count, Equals, 2)
// The 0th CellStyleXf could just be getting the zero values by default
c.Assert(styles.CellStyleXfs.Xf[0].FontId, Equals, 0)
c.Assert(styles.CellStyleXfs.Xf[0].FillId, Equals, 0)
c.Assert(styles.CellStyleXfs.Xf[0].BorderId, Equals, 0)
c.Assert(styles.CellXfs.Count, Equals, 2)
c.Assert(styles.CellXfs.Xf[0].FontId, Equals, 0)
c.Assert(styles.CellXfs.Xf[0].FillId, Equals, 0)
c.Assert(styles.CellXfs.Xf[0].BorderId, Equals, 0)
// Finally we check that the cell points to the right CellXf /
// CellStyleXf.
c.Assert(worksheet.SheetData.Row[0].C[0].S, Equals, 1)
c.Assert(worksheet.SheetData.Row[0].C[1].S, Equals, 1)
}
// If the column width is not customised, the xslxCol.CustomWidth field is set to 0.
func (s *SheetSuite) TestMakeXLSXSheetDefaultsCustomColWidth(c *C) {
file := NewFile()
sheet := file.AddSheet("Sheet1")
row := sheet.AddRow()
cell1 := row.AddCell()
cell1.Value = "A cell!"
refTable := NewSharedStringRefTable()
styles := newXlsxStyleSheet(nil)
worksheet := sheet.makeXLSXSheet(refTable, styles)
c.Assert(worksheet.Cols.Col[0].CustomWidth, Equals, 0)
}
// If the column width is customised, the xslxCol.CustomWidth field is set to 1.
func (s *SheetSuite) TestMakeXLSXSheetSetsCustomColWidth(c *C) {
file := NewFile()
sheet := file.AddSheet("Sheet1")
err := sheet.SetColWidth(0, 0, 10.5)
c.Assert(err, IsNil)
refTable := NewSharedStringRefTable()
styles := newXlsxStyleSheet(nil)
worksheet := sheet.makeXLSXSheet(refTable, styles)
c.Assert(worksheet.Cols.Col[0].CustomWidth, Equals, 1)
}
func (s *SheetSuite) TestMarshalSheet(c *C) {
file := NewFile()
sheet := file.AddSheet("Sheet1")
row := sheet.AddRow()
cell := row.AddCell()
cell.Value = "A cell!"
refTable := NewSharedStringRefTable()
styles := newXlsxStyleSheet(nil)
xSheet := sheet.makeXLSXSheet(refTable, styles)
output := bytes.NewBufferString(xml.Header)
body, err := xml.Marshal(xSheet)
c.Assert(err, IsNil)
c.Assert(body, NotNil)
_, err = output.Write(body)
c.Assert(err, IsNil)
expectedXLSXSheet := `
0
&C&"Times New Roman,Regular"&12&A&C&"Times New Roman,Regular"&12Page &P`
c.Assert(output.String(), Equals, expectedXLSXSheet)
}
func (s *SheetSuite) TestMarshalSheetWithMultipleCells(c *C) {
file := NewFile()
sheet := file.AddSheet("Sheet1")
row := sheet.AddRow()
cell := row.AddCell()
cell.Value = "A cell (with value 1)!"
cell = row.AddCell()
cell.Value = "A cell (with value 2)!"
refTable := NewSharedStringRefTable()
styles := newXlsxStyleSheet(nil)
xSheet := sheet.makeXLSXSheet(refTable, styles)
output := bytes.NewBufferString(xml.Header)
body, err := xml.Marshal(xSheet)
c.Assert(err, IsNil)
c.Assert(body, NotNil)
_, err = output.Write(body)
c.Assert(err, IsNil)
expectedXLSXSheet := `
01
&C&"Times New Roman,Regular"&12&A&C&"Times New Roman,Regular"&12Page &P`
c.Assert(output.String(), Equals, expectedXLSXSheet)
}
func (s *SheetSuite) TestSetColWidth(c *C) {
file := NewFile()
sheet := file.AddSheet("Sheet1")
_ = sheet.SetColWidth(0, 0, 10.5)
_ = sheet.SetColWidth(1, 5, 11)
c.Assert(sheet.Cols[0].Width, Equals, 10.5)
c.Assert(sheet.Cols[0].Max, Equals, 1)
c.Assert(sheet.Cols[0].Min, Equals, 1)
c.Assert(sheet.Cols[1].Width, Equals, float64(11))
c.Assert(sheet.Cols[1].Max, Equals, 6)
c.Assert(sheet.Cols[1].Min, Equals, 2)
}
func (s *SheetSuite) TestSetRowHeightCM(c *C) {
file := NewFile()
sheet := file.AddSheet("Sheet1")
row := sheet.AddRow()
row.SetHeightCM(1.5)
c.Assert(row.Height, Equals, 42.51968505)
}
func (s *SheetSuite) TestAlignment(c *C) {
leftalign := Alignment{Horizontal: "left"}
centerHalign := Alignment{Horizontal: "center"}
rightalign := Alignment{Horizontal: "right"}
file := NewFile()
sheet := file.AddSheet("Sheet1")
style := NewStyle()
hrow := sheet.AddRow()
// Horizontals
cell := hrow.AddCell()
cell.Value = "left"
style.Alignment = leftalign
style.ApplyAlignment = true
cell.SetStyle(style)
style = NewStyle()
cell = hrow.AddCell()
cell.Value = "centerH"
style.Alignment = centerHalign
style.ApplyAlignment = true
cell.SetStyle(style)
style = NewStyle()
cell = hrow.AddCell()
cell.Value = "right"
style.Alignment = rightalign
style.ApplyAlignment = true
cell.SetStyle(style)
// Verticals
topalign := Alignment{Vertical: "top"}
centerValign := Alignment{Vertical: "center"}
bottomalign := Alignment{Vertical: "bottom"}
style = NewStyle()
vrow := sheet.AddRow()
cell = vrow.AddCell()
cell.Value = "top"
style.Alignment = topalign
style.ApplyAlignment = true
cell.SetStyle(style)
style = NewStyle()
cell = vrow.AddCell()
cell.Value = "centerV"
style.Alignment = centerValign
style.ApplyAlignment = true
cell.SetStyle(style)
style = NewStyle()
cell = vrow.AddCell()
cell.Value = "bottom"
style.Alignment = bottomalign
style.ApplyAlignment = true
cell.SetStyle(style)
parts, err := file.MarshallParts()
c.Assert(err, IsNil)
stylepart := parts["xl/styles.xml"]
shouldbe := `
`
output := bytes.NewBufferString(shouldbe)
c.Assert(output.String(), Equals, stylepart)
}