github.com/shakinm/xlsReader@v0.9.12/xls/sheet.go (about)

     1  package xls
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/shakinm/xlsReader/helpers"
     7  	"github.com/shakinm/xlsReader/xls/record"
     8  	"github.com/shakinm/xlsReader/xls/structure"
     9  )
    10  
    11  type rw struct {
    12  	cols map[int]structure.CellData
    13  }
    14  
    15  type Sheet struct {
    16  	boundSheet    *record.BoundSheet
    17  	rows          map[int]*rw
    18  	wb            *Workbook
    19  	maxCol        int // maxCol index, countCol=maxCol+1
    20  	maxRow        int // maxRow index, countRow=maxRow+1
    21  	hasAutofilter bool
    22  }
    23  
    24  func (s *Sheet) GetName() string {
    25  	return s.boundSheet.GetName()
    26  }
    27  
    28  // Get row by index
    29  
    30  func (s *Sheet) GetRow(index int) (row *rw, err error) {
    31  
    32  	if row, ok := s.rows[index]; ok {
    33  		return row, err
    34  	} else {
    35  		r := new(rw)
    36  		r.cols = make(map[int]structure.CellData)
    37  		return r, nil
    38  	}
    39  }
    40  
    41  func (rw *rw) GetCol(index int) (c structure.CellData, err error) {
    42  
    43  	if col, ok := rw.cols[index]; ok {
    44  		return col, err
    45  	} else {
    46  		c = new(record.FakeBlank)
    47  		return c, nil
    48  	}
    49  
    50  }
    51  
    52  func (rw *rw) GetCols() (cols []structure.CellData) {
    53  
    54  	var maxColKey int
    55  
    56  	for k, _ := range rw.cols {
    57  		if k > maxColKey {
    58  			maxColKey = k
    59  		}
    60  	}
    61  
    62  	for i := 0; i <= maxColKey; i++ {
    63  		if rw.cols[i] == nil {
    64  			cols = append(cols, new(record.FakeBlank))
    65  		} else {
    66  			cols = append(cols, rw.cols[i])
    67  		}
    68  	}
    69  
    70  	return cols
    71  }
    72  
    73  // Get all rows
    74  func (s *Sheet) GetRows() (rows []*rw) {
    75  	for i := 0; i <= s.GetNumberRows()-1; i++ {
    76  		if s.rows[i] == nil {
    77  			r := new(rw)
    78  			r.cols = make(map[int]structure.CellData)
    79  			rows = append(rows, r)
    80  		} else {
    81  			rows = append(rows, s.rows[i])
    82  		}
    83  	}
    84  
    85  	return rows
    86  }
    87  
    88  // Get number of rows
    89  func (s *Sheet) GetNumberRows() (n int) {
    90  
    91  	var maxRowKey int
    92  
    93  	for k, _ := range s.rows {
    94  		if k > maxRowKey {
    95  			maxRowKey = k
    96  		}
    97  	}
    98  
    99  	return maxRowKey + 1
   100  }
   101  
   102  func (s *Sheet) read(stream []byte) (err error) { // nolint: gocyclo
   103  
   104  	var point int64
   105  	point = int64(helpers.BytesToUint32(s.boundSheet.LbPlyPos[:]))
   106  	var sPoint int64
   107  	eof := false
   108  	records := make(map[string]string )
   109  Next:
   110  
   111  	recordNumber := stream[point : point+2]
   112  	recordDataLength := int64(helpers.BytesToUint16(stream[point+2 : point+4]))
   113  	sPoint = point + 4
   114  	records[fmt.Sprintf("%x",recordNumber)]=fmt.Sprintf("%x",recordNumber)
   115  	if bytes.Compare(recordNumber, record.AutofilterInfoRecord[:]) == 0 {
   116  		c := new(record.AutofilterInfo)
   117  		c.Read(stream[sPoint : sPoint+recordDataLength])
   118  		if c.GetCountEntries() > 0 {
   119  			s.hasAutofilter = true
   120  		} else {
   121  			s.hasAutofilter = false
   122  		}
   123  		goto EIF
   124  
   125  	}
   126  
   127  	//LABELSST - String constant that uses BIFF8 shared string table (new to BIFF8)
   128  	if bytes.Compare(recordNumber, record.LabelSStRecord[:]) == 0 {
   129  		c := new(record.LabelSSt)
   130  		c.Read(stream[sPoint:sPoint+recordDataLength], &s.wb.sst)
   131  		s.addCell(c, c.GetRow(), c.GetCol())
   132  		goto EIF
   133  	}
   134  
   135  	//LABEL - Cell Value, String Constant
   136  	if bytes.Compare(recordNumber, record.LabelRecord[:]) == 0 {
   137  		if bytes.Compare(s.wb.vers[:], record.FlagBIFF8) == 0 {
   138  			c := new(record.LabelBIFF8)
   139  			c.Read(stream[sPoint : sPoint+recordDataLength])
   140  			s.addCell(c, c.GetRow(), c.GetCol())
   141  		} else {
   142  			c := new(record.LabelBIFF5)
   143  			c.Read(stream[sPoint : sPoint+recordDataLength])
   144  			s.addCell(c, c.GetRow(), c.GetCol())
   145  		}
   146  
   147  		goto EIF
   148  	}
   149  
   150  	if bytes.Compare(recordNumber, []byte{0xFD, 0x00}) == 0 {
   151  		//todo: сделать
   152  		goto EIF
   153  	}
   154  
   155  	//ARRAY - An array-entered formula
   156  	if bytes.Compare(recordNumber, record.ArrayRecord[:]) == 0 {
   157  		//todo: сделать
   158  		goto EIF
   159  	}
   160  	//BLANK - An empty col
   161  	if bytes.Compare(recordNumber, record.BlankRecord[:]) == 0 {
   162  		c := new(record.Blank)
   163  		c.Read(stream[sPoint : sPoint+recordDataLength])
   164  		s.addCell(c, c.GetRow(), c.GetCol())
   165  		goto EIF
   166  	}
   167  
   168  	//BOOLERR - A Boolean or error value
   169  	if bytes.Compare(recordNumber, record.BoolErrRecord[:]) == 0 {
   170  		c := new(record.BoolErr)
   171  		c.Read(stream[sPoint : sPoint+recordDataLength])
   172  		s.addCell(c, c.GetRow(), c.GetCol())
   173  		goto EIF
   174  	}
   175  
   176  	//FORMULA - A col formula, stored as parse tokens
   177  	if bytes.Compare(recordNumber, record.FormulaRecord[:]) == 0 {
   178  		//todo: сделать
   179  		goto EIF
   180  	}
   181  
   182  	//NUMBER  - An IEEE floating-point number
   183  	if bytes.Compare(recordNumber, record.NumberRecord[:]) == 0 {
   184  		c := new(record.Number)
   185  		c.Read(stream[sPoint : sPoint+recordDataLength])
   186  		s.addCell(c, c.GetRow(), c.GetCol())
   187  		goto EIF
   188  	}
   189  
   190  	//MULBLANK - Multiple empty rows (new to BIFF5)
   191  	if bytes.Compare(recordNumber, record.MulBlankRecord[:]) == 0 {
   192  		c := new(record.MulBlank)
   193  		c.Read(stream[sPoint : sPoint+recordDataLength])
   194  		blRecords := c.GetArrayBlRecord()
   195  		for i := 0; i <= len(blRecords)-1; i++ {
   196  			s.addCell(blRecords[i].Get(), blRecords[i].GetRow(), blRecords[i].GetCol())
   197  		}
   198  		goto EIF
   199  	}
   200  
   201  	//RK - An RK number
   202  	if bytes.Compare(recordNumber, record.RkRecord[:]) == 0 {
   203  		c := new(record.Rk)
   204  		c.Read(stream[sPoint : sPoint+recordDataLength])
   205  		s.addCell(c, c.GetRow(), c.GetCol())
   206  		goto EIF
   207  	}
   208  
   209  	//MULRK - Multiple RK numbers (new to BIFF5)
   210  	if bytes.Compare(recordNumber, record.MulRKRecord[:]) == 0 {
   211  		c := new(record.MulRk)
   212  		c.Read(stream[sPoint : sPoint+recordDataLength])
   213  		rkRecords := c.GetArrayRKRecord()
   214  		for i := 0; i <= len(rkRecords)-1; i++ {
   215  			s.addCell(rkRecords[i].Get(), rkRecords[i].GetRow(), rkRecords[i].GetCol())
   216  		}
   217  		goto EIF
   218  
   219  	}
   220  
   221  	//RSTRING - Cell with character formatting
   222  	if bytes.Compare(recordNumber, record.RStringRecord[:]) == 0 {
   223  		//todo: сделать
   224  		goto EIF
   225  	}
   226  
   227  	//SHRFMLA - A shared formula (new to BIFF5)
   228  	if bytes.Compare(recordNumber, record.SharedFormulaRecord[:]) == 0 {
   229  		//todo: сделать
   230  		goto EIF
   231  	}
   232  
   233  	//STRING - A string that represents the result of a formula
   234  	if bytes.Compare(recordNumber, record.StringRecord[:]) == 0 {
   235  		//todo: сделать
   236  		goto EIF
   237  	}
   238  
   239  	if bytes.Compare(recordNumber, record.RowRecord[:]) == 0 {
   240  		//todo: сделать
   241  		goto EIF
   242  	}
   243  
   244  	//EOF
   245  	if bytes.Compare(recordNumber, record.EOFRecord[:]) == 0 && recordDataLength == 0 {
   246  		eof = true
   247  	}
   248  EIF:
   249  	point = point + recordDataLength + 4
   250  	if !eof {
   251  		goto Next
   252  	}
   253  
   254  	return
   255  
   256  }
   257  
   258  func (s *Sheet) addCell(cd structure.CellData, row [2]byte, column [2]byte) {
   259  
   260  	r := int(helpers.BytesToUint16(row[:]))
   261  	c := int(helpers.BytesToUint16(column[:]))
   262  
   263  	if s.rows == nil {
   264  		s.rows = map[int]*rw{}
   265  	}
   266  	if _, ok := s.rows[r]; !ok {
   267  		s.rows[r] = new(rw)
   268  
   269  		if _, ok := s.rows[r].cols[c]; !ok {
   270  
   271  			colVal := map[int]structure.CellData{}
   272  			colVal[c] = cd
   273  
   274  			s.rows[r].cols = colVal
   275  		}
   276  
   277  	}
   278  
   279  	s.rows[r].cols[c] = cd
   280  
   281  }