Browse Source

Merge branch 'master' of github.com:tealeg/xlsx

Geoffrey J. Teale 11 years ago
parent
commit
607ad9c7cd
10 changed files with 121 additions and 12 deletions
  1. 34 0
      FileToSlice.go
  2. 35 0
      FileToSlice_test.go
  3. 7 0
      cell.go
  4. 5 0
      col.go
  5. 1 0
      col_test.go
  6. 2 1
      file_test.go
  7. 19 7
      lib.go
  8. 2 1
      row.go
  9. 1 0
      sheet_test.go
  10. 15 3
      worksheet.go

+ 34 - 0
FileToSlice.go

@@ -0,0 +1,34 @@
+package xlsx
+
+// get all raw data from excel
+// output index mean=> sheetIndex ,row ,cell ,value
+// not remove any cells
+func FileToSlice(path string) ([][][]string, error) {
+	f, err := OpenFile(path)
+	if err != nil {
+		return nil, err
+	}
+	return f.ToSlice()
+}
+
+// get all raw data from excel
+// output index mean=> sheetIndex ,row ,cell ,value
+// not remove any cells
+func (file *File) ToSlice() (output [][][]string, err error) {
+	output = [][][]string{}
+	for _, sheet := range file.Sheets {
+		s := [][]string{}
+		for _, row := range sheet.Rows {
+			if row == nil {
+				continue
+			}
+			r := []string{}
+			for _, cell := range row.Cells {
+				r = append(r, cell.String())
+			}
+			s = append(s, r)
+		}
+		output = append(output, s)
+	}
+	return output, nil
+}

+ 35 - 0
FileToSlice_test.go

@@ -0,0 +1,35 @@
+package xlsx
+
+import (
+	. "gopkg.in/check.v1"
+)
+
+type SliceReaderSuite struct{}
+
+var _ = Suite(&SliceReaderSuite{})
+
+func (s *SliceReaderSuite) TestFileToSlice(c *C) {
+	output, err := FileToSlice("testfile.xlsx")
+	c.Assert(err, IsNil)
+	fileToSliceCheckOutput(c, output)
+}
+
+func (s *SliceReaderSuite) TestFileObjToSlice(c *C) {
+	f, err := OpenFile("testfile.xlsx")
+	output, err := f.ToSlice()
+	c.Assert(err, IsNil)
+	fileToSliceCheckOutput(c, output)
+}
+
+func fileToSliceCheckOutput(c *C, output [][][]string) {
+	c.Assert(len(output), Equals, 3)
+	c.Assert(len(output[0]), Equals, 2)
+	c.Assert(len(output[0][0]), Equals, 2)
+	c.Assert(output[0][0][0], Equals, "Foo")
+	c.Assert(output[0][0][1], Equals, "Bar")
+	c.Assert(len(output[0][1]), Equals, 2)
+	c.Assert(output[0][1][0], Equals, "Baz")
+	c.Assert(output[0][1][1], Equals, "Quuk")
+	c.Assert(len(output[1]), Equals, 0)
+	c.Assert(len(output[2]), Equals, 0)
+}

+ 7 - 0
cell.go

@@ -59,6 +59,7 @@ type Cell struct {
 	styles         *xlsxStyles
 	numFmtRefTable map[int]xlsxNumFmt
 	date1904       bool
+	Hidden         bool
 }
 
 // CellInterface defines the public API of the Cell.
@@ -118,6 +119,12 @@ func (c *Cell) GetStyle() Style {
 
 // The number format string is returnable from a cell.
 func (c *Cell) GetNumberFormat() string {
+	if c.styles == nil {
+		return ""
+	}
+	if c.styles.CellXfs == nil {
+		return ""
+	}
 	var numberFormat string = ""
 	if c.styleIndex > -1 && c.styleIndex <= len(c.styles.CellXfs) {
 		xf := c.styles.CellXfs[c.styleIndex]

+ 5 - 0
col.go

@@ -0,0 +1,5 @@
+package xlsx
+
+type Col struct {
+	Hidden bool
+}

+ 1 - 0
col_test.go

@@ -0,0 +1 @@
+package xlsx

+ 2 - 1
file_test.go

@@ -2,8 +2,8 @@ package xlsx
 
 import (
 	"encoding/xml"
-	. "gopkg.in/check.v1"
 	"path/filepath"
+	. "gopkg.in/check.v1"
 )
 
 type FileSuite struct{}
@@ -283,6 +283,7 @@ func (l *FileSuite) TestMarshalFile(c *C) {
 	expectedSheet := `<?xml version="1.0" encoding="UTF-8"?>
   <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
     <dimension ref="A1:A1"></dimension>
+    <cols></cols>
     <sheetData>
       <row r="1">
         <c r="A1" t="s">

+ 19 - 7
lib.go

@@ -6,9 +6,7 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"math"
 	"path"
-	"runtime"
 	"strconv"
 	"strings"
 )
@@ -215,11 +213,7 @@ func calculateMaxMinFromWorksheet(worksheet *xlsxWorksheet) (minx, miny, maxx, m
 	// Note, this method could be very slow for large spreadsheets.
 	var x, y int
 	var maxVal int
-	if runtime.GOARCH == "386" {
-		maxVal = math.MaxInt32
-	} else {
-		maxVal = math.MaxInt64
-	}
+	maxVal = int(^uint(0) >> 1)
 	minx = maxVal
 	miny = maxVal
 	maxy = 0
@@ -334,6 +328,7 @@ func getValueFromCellData(rawcell xlsxC, reftable *RefTable) string {
 // the value references from the reference table and stores them in
 func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, int, int) {
 	var rows []*Row
+	var cols []*Col
 	var row *Row
 	var minCol, maxCol, minRow, maxRow, colCount, rowCount int
 	var reftable *RefTable
@@ -355,7 +350,21 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, int, int)
 	rowCount = (maxRow - minRow) + 1
 	colCount = (maxCol - minCol) + 1
 	rows = make([]*Row, rowCount)
+	cols = make([]*Col, colCount)
 	insertRowIndex = minRow
+	for i := range cols {
+		cols[i] = &Col{
+			Hidden: false,
+		}
+	}
+	for colIndex := 0; colIndex < len(Worksheet.Cols.Col); colIndex++ {
+		rawcol := Worksheet.Cols.Col[colIndex]
+		for c := rawcol.Min - 1; c < colCount && c < rawcol.Max; c++ {
+			cols[c] = &Col{
+				Hidden: rawcol.Hidden,
+			}
+		}
+	}
 	for rowIndex := 0; rowIndex < len(Worksheet.SheetData.Row); rowIndex++ {
 		rawrow := Worksheet.SheetData.Row[rowIndex]
 		// Some spreadsheets will omit blank rows from the
@@ -371,6 +380,8 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, int, int)
 		} else {
 			row = makeRowFromRaw(rawrow)
 		}
+		
+		row.Hidden = rawrow.Hidden
 
 		insertColIndex = minCol
 		for _, rawcell := range rawrow.C {
@@ -389,6 +400,7 @@ func readRowsFromSheet(Worksheet *xlsxWorksheet, file *File) ([]*Row, int, int)
 			row.Cells[cellX].styles = file.styles
 			row.Cells[cellX].numFmtRefTable = file.numFmtRefTable
 			row.Cells[cellX].date1904 = file.Date1904
+			row.Cells[cellX].Hidden = rawrow.Hidden || cols[cellX].Hidden
 			insertColIndex++
 		}
 		if len(rows) > insertRowIndex-minRow {

+ 2 - 1
row.go

@@ -1,7 +1,8 @@
 package xlsx
 
 type Row struct {
-	Cells []*Cell
+	Cells  []*Cell
+	Hidden bool
 }
 
 func (r *Row) AddCell() *Cell {

+ 1 - 0
sheet_test.go

@@ -65,6 +65,7 @@ func (s *SheetSuite) TestMarshalSheet(c *C) {
 	expectedXLSXSheet := `<?xml version="1.0" encoding="UTF-8"?>
   <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
     <dimension ref="A1:A1"></dimension>
+    <cols></cols>
     <sheetData>
       <row r="1">
         <c r="A1" t="s">

+ 15 - 3
worksheet.go

@@ -11,9 +11,20 @@ import (
 type xlsxWorksheet struct {
 	XMLName   xml.Name      `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main worksheet"`
 	Dimension xlsxDimension `xml:"dimension"`
+	Cols      xslxCols      `xml:"cols,omitempty"`
 	SheetData xlsxSheetData `xml:"sheetData"`
 }
 
+type xslxCols struct {
+	Col []xlsxCol `xml:"col"`
+}
+
+type xlsxCol struct {
+	Min    int  `xml:"min,attr"`
+	Max    int  `xml:"max,attr"`
+	Hidden bool `xml:"hidden,attr,omitempty"`
+}
+
 // xlsxDimension directly maps the dimension element in the namespace
 // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
 // currently I have not checked it for completeness - it does as much
@@ -36,9 +47,10 @@ type xlsxSheetData struct {
 // currently I have not checked it for completeness - it does as much
 // as I need.
 type xlsxRow struct {
-	R     int     `xml:"r,attr"`
-	Spans string  `xml:"spans,attr,omitempty"`
-	C     []xlsxC `xml:"c"`
+	R      int     `xml:"r,attr"`
+	Spans  string  `xml:"spans,attr,omitempty"`
+	Hidden bool    `xml:"hidden,attr,omitempty"`
+	C      []xlsxC `xml:"c"`
 }
 
 // xlsxC directly maps the c element in the namespace