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

     1  package xls
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"github.com/shakinm/xlsReader/helpers"
     7  	"github.com/shakinm/xlsReader/xls/record"
     8  )
     9  
    10  // Workbook struct
    11  type Workbook struct {
    12  	sheets   []Sheet
    13  	codepage record.CodePage
    14  	sst      record.SST
    15  	xf       []record.XF
    16  	formats  map[int]record.Format
    17  	vers     [2]byte
    18  }
    19  
    20  // GetNumberSheets - Number of sheets in the workbook
    21  func (wb *Workbook) GetNumberSheets() int {
    22  	return len(wb.sheets)
    23  }
    24  
    25  // GetSheets - Get sheets in the workbook
    26  func (wb *Workbook) GetSheets() []Sheet {
    27  	return wb.sheets
    28  }
    29  
    30  // GetSheet - Get Sheet by ID
    31  func (wb *Workbook) GetSheet(sheetID int) (sheet *Sheet, err error) { // nolint: golint
    32  
    33  	if len(wb.sheets) >= 1 && len(wb.sheets) >= sheetID {
    34  		return &wb.sheets[sheetID], err
    35  	}
    36  
    37  	return nil, errors.New("error. Sheet not found")
    38  }
    39  
    40  // GetXF -  Return Extended Format Record by index
    41  func (wb *Workbook) GetXFbyIndex(index int) record.XF {
    42  	if len(wb.xf)-1<index {
    43  		return wb.xf[15]
    44  	}
    45  	return wb.xf[index]
    46  }
    47  
    48  // GetXF -  Return FORMAT record describes a number format in the workbook
    49  func (wb *Workbook) GetFormatByIndex(index int) record.Format {
    50  	return wb.formats[index]
    51  }
    52  
    53  // GetCodePage - codepage
    54  func (wb *Workbook) GetCodePage() record.CodePage {
    55  	return wb.codepage
    56  }
    57  
    58  // GetVersionBIFF - version BIFF
    59  func (wb *Workbook) GetVersionBIFF() []byte {
    60  	return wb.vers[:]
    61  }
    62  
    63  func (wb *Workbook) addSheet(bs *record.BoundSheet) (sheet Sheet) { // nolint: golint
    64  	sheet.boundSheet = bs
    65  	sheet.wb = wb
    66  	wb.sheets = append(wb.sheets, sheet)
    67  	return sheet
    68  }
    69  
    70  func (wb *Workbook) read(stream []byte) (err error) { // nolint: gocyclo
    71  
    72  	var point int32
    73  	var SSTContinue = false
    74  	var sPoint, prevLen int32
    75  	var readType string
    76  	var grbit byte
    77  	var grbitOffset int32
    78  
    79  	eof := false
    80  
    81  Next:
    82  
    83  	recordNumber := stream[point : point+2]
    84  	recordDataLength := int32(helpers.BytesToUint16(stream[point+2 : point+4]))
    85  	sPoint = point + 4
    86  
    87  	if bytes.Compare(recordNumber, record.IndexRecord[:]) == 0 {
    88  		_ = new(record.LabelSSt)
    89  		goto EIF
    90  	}
    91  
    92  	//BoundSheet
    93  
    94  	if bytes.Compare(recordNumber, record.BoundSheetRecord[:]) == 0 {
    95  		var bs record.BoundSheet
    96  		bs.Read(stream[sPoint+grbitOffset : sPoint+recordDataLength], wb.vers[:])
    97  		_ = wb.addSheet(&bs)
    98  		goto EIF
    99  	}
   100  
   101  	//Continue
   102  	if bytes.Compare(recordNumber, record.ContinueRecord[:]) == 0 {
   103  
   104  		if SSTContinue {
   105  			readType = "continue"
   106  
   107  			if len(wb.sst.RgbSrc) == 0  {
   108  				grbitOffset = 0
   109  			} else {
   110  				grbitOffset = 1
   111  			}
   112  
   113  			grbit = stream[sPoint]
   114  
   115  			wb.sst.RgbSrc = append(wb.sst.RgbSrc, stream[sPoint+grbitOffset:sPoint+recordDataLength]...)
   116  			wb.sst.Read(readType, grbit, prevLen)
   117  		}
   118  		goto EIF
   119  	}
   120  
   121  	//SST
   122  	if bytes.Compare(recordNumber, record.SSTRecord[:]) == 0 {
   123  		wb.sst.NewSST(stream[sPoint : sPoint+recordDataLength])
   124  
   125  		wb.sst.Read(readType, grbit, prevLen)
   126  		totalSSt := helpers.BytesToUint32(wb.sst.CstTotal[:])
   127  		if recordDataLength >= 8224 || uint32(len(wb.sst.Rgb)) < totalSSt-1 {
   128  			SSTContinue = true
   129  		}
   130  		goto EIF
   131  	}
   132  
   133  	if bytes.Compare(recordNumber, record.XFRecord[:]) == 0 {
   134  		xf := new(record.XF)
   135  		xf.Read(stream[sPoint : sPoint+recordDataLength])
   136  		wb.xf=append(wb.xf, *xf)
   137  		goto EIF
   138  	}
   139  
   140  	if bytes.Compare(recordNumber, record.FormatRecord[:]) == 0 {
   141  		format := new(record.Format)
   142  
   143  		format.Read(stream[sPoint : sPoint+recordDataLength], wb.vers[:])
   144  
   145  		if wb.formats==nil {
   146  			wb.formats = make(map[int]record.Format,0)
   147  		}
   148  		wb.formats[format.GetIndex()]=*format
   149  		goto EIF
   150  	}
   151  
   152  	//CodePage
   153  	if bytes.Compare(recordNumber, record.CodePageRecord[:]) == 0 {
   154  		wb.codepage.Read(stream[sPoint : sPoint+recordDataLength])
   155  		goto EIF
   156  	}
   157  
   158  	//EOF
   159  	if bytes.Compare(recordNumber, record.EOFRecord[:]) == 0 && recordDataLength == 0 {
   160  		eof = true
   161  	}
   162  
   163  	if bytes.Compare(recordNumber, record.BOFMARKS[:]) == 0   {
   164  		copy(wb.vers[:], stream[sPoint : sPoint+2])
   165  		goto EIF
   166  	}
   167  
   168  EIF:
   169  	point = point + recordDataLength + 4
   170  	if !eof {
   171  		goto Next
   172  	}
   173  
   174  	return err
   175  }