This optimizes internal functions signature and mutex declarations

This commit is contained in:
xuri 2023-04-24 00:02:13 +08:00
parent 787453c6f0
commit 93c72b4d55
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
20 changed files with 168 additions and 168 deletions

View File

@ -60,8 +60,8 @@ func (f *File) adjustHelper(sheet string, dir adjustDirection, num, offset int)
if err = f.adjustCalcChain(dir, num, offset, sheetID); err != nil { if err = f.adjustCalcChain(dir, num, offset, sheetID); err != nil {
return err return err
} }
checkSheet(ws) ws.checkSheet()
_ = checkRow(ws) _ = ws.checkRow()
if ws.MergeCells != nil && len(ws.MergeCells.Cells) == 0 { if ws.MergeCells != nil && len(ws.MergeCells.Cells) == 0 {
ws.MergeCells = nil ws.MergeCells = nil

10
calc.go
View File

@ -215,7 +215,7 @@ var (
// calcContext defines the formula execution context. // calcContext defines the formula execution context.
type calcContext struct { type calcContext struct {
sync.Mutex mu sync.Mutex
entry string entry string
maxCalcIterations uint maxCalcIterations uint
iterations map[string]uint iterations map[string]uint
@ -1553,19 +1553,19 @@ func (f *File) cellResolver(ctx *calcContext, sheet, cell string) (formulaArg, e
) )
ref := fmt.Sprintf("%s!%s", sheet, cell) ref := fmt.Sprintf("%s!%s", sheet, cell)
if formula, _ := f.GetCellFormula(sheet, cell); len(formula) != 0 { if formula, _ := f.GetCellFormula(sheet, cell); len(formula) != 0 {
ctx.Lock() ctx.mu.Lock()
if ctx.entry != ref { if ctx.entry != ref {
if ctx.iterations[ref] <= f.options.MaxCalcIterations { if ctx.iterations[ref] <= f.options.MaxCalcIterations {
ctx.iterations[ref]++ ctx.iterations[ref]++
ctx.Unlock() ctx.mu.Unlock()
arg, _ = f.calcCellValue(ctx, sheet, cell) arg, _ = f.calcCellValue(ctx, sheet, cell)
ctx.iterationsCache[ref] = arg ctx.iterationsCache[ref] = arg
return arg, nil return arg, nil
} }
ctx.Unlock() ctx.mu.Unlock()
return ctx.iterationsCache[ref], nil return ctx.iterationsCache[ref], nil
} }
ctx.Unlock() ctx.mu.Unlock()
} }
if value, err = f.GetCellValue(sheet, cell, Options{RawCellValue: true}); err != nil { if value, err = f.GetCellValue(sheet, cell, Options{RawCellValue: true}); err != nil {
return arg, err return arg, err

View File

@ -58,8 +58,8 @@ func (f *File) deleteCalcChain(index int, cell string) error {
if err != nil { if err != nil {
return err return err
} }
content.Lock() content.mu.Lock()
defer content.Unlock() defer content.mu.Unlock()
for k, v := range content.Overrides { for k, v := range content.Overrides {
if v.PartName == "/xl/calcChain.xml" { if v.PartName == "/xl/calcChain.xml" {
content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...) content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...)

92
cell.go
View File

@ -236,13 +236,13 @@ func (f *File) setCellTimeFunc(sheet, cell string, value time.Time) error {
if err != nil { if err != nil {
return err return err
} }
c, col, row, err := f.prepareCell(ws, cell) c, col, row, err := ws.prepareCell(cell)
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
c.S = f.prepareCellStyle(ws, col, row, c.S) c.S = ws.prepareCellStyle(col, row, c.S)
ws.Unlock() ws.mu.Unlock()
var date1904, isNum bool var date1904, isNum bool
wb, err := f.workbookReader() wb, err := f.workbookReader()
if err != nil { if err != nil {
@ -292,13 +292,13 @@ func (f *File) SetCellInt(sheet, cell string, value int) error {
if err != nil { if err != nil {
return err return err
} }
c, col, row, err := f.prepareCell(ws, cell) c, col, row, err := ws.prepareCell(cell)
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
c.S = f.prepareCellStyle(ws, col, row, c.S) c.S = ws.prepareCellStyle(col, row, c.S)
c.T, c.V = setCellInt(value) c.T, c.V = setCellInt(value)
c.IS = nil c.IS = nil
return f.removeFormula(c, ws, sheet) return f.removeFormula(c, ws, sheet)
@ -318,13 +318,13 @@ func (f *File) SetCellBool(sheet, cell string, value bool) error {
if err != nil { if err != nil {
return err return err
} }
c, col, row, err := f.prepareCell(ws, cell) c, col, row, err := ws.prepareCell(cell)
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
c.S = f.prepareCellStyle(ws, col, row, c.S) c.S = ws.prepareCellStyle(col, row, c.S)
c.T, c.V = setCellBool(value) c.T, c.V = setCellBool(value)
c.IS = nil c.IS = nil
return f.removeFormula(c, ws, sheet) return f.removeFormula(c, ws, sheet)
@ -355,13 +355,13 @@ func (f *File) SetCellFloat(sheet, cell string, value float64, precision, bitSiz
if err != nil { if err != nil {
return err return err
} }
c, col, row, err := f.prepareCell(ws, cell) c, col, row, err := ws.prepareCell(cell)
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
c.S = f.prepareCellStyle(ws, col, row, c.S) c.S = ws.prepareCellStyle(col, row, c.S)
c.T, c.V = setCellFloat(value, precision, bitSize) c.T, c.V = setCellFloat(value, precision, bitSize)
c.IS = nil c.IS = nil
return f.removeFormula(c, ws, sheet) return f.removeFormula(c, ws, sheet)
@ -381,13 +381,13 @@ func (f *File) SetCellStr(sheet, cell, value string) error {
if err != nil { if err != nil {
return err return err
} }
c, col, row, err := f.prepareCell(ws, cell) c, col, row, err := ws.prepareCell(cell)
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
c.S = f.prepareCellStyle(ws, col, row, c.S) c.S = ws.prepareCellStyle(col, row, c.S)
if c.T, c.V, err = f.setCellString(value); err != nil { if c.T, c.V, err = f.setCellString(value); err != nil {
return err return err
} }
@ -413,8 +413,8 @@ func (f *File) setCellString(value string) (t, v string, err error) {
// sharedStringsLoader load shared string table from system temporary file to // sharedStringsLoader load shared string table from system temporary file to
// memory, and reset shared string table for reader. // memory, and reset shared string table for reader.
func (f *File) sharedStringsLoader() (err error) { func (f *File) sharedStringsLoader() (err error) {
f.Lock() f.mu.Lock()
defer f.Unlock() defer f.mu.Unlock()
if path, ok := f.tempFiles.Load(defaultXMLPathSharedStrings); ok { if path, ok := f.tempFiles.Load(defaultXMLPathSharedStrings); ok {
f.Pkg.Store(defaultXMLPathSharedStrings, f.readBytes(defaultXMLPathSharedStrings)) f.Pkg.Store(defaultXMLPathSharedStrings, f.readBytes(defaultXMLPathSharedStrings))
f.tempFiles.Delete(defaultXMLPathSharedStrings) f.tempFiles.Delete(defaultXMLPathSharedStrings)
@ -443,8 +443,8 @@ func (f *File) setSharedString(val string) (int, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
f.Lock() f.mu.Lock()
defer f.Unlock() defer f.mu.Unlock()
if i, ok := f.sharedStringsMap[val]; ok { if i, ok := f.sharedStringsMap[val]; ok {
return i, nil return i, nil
} }
@ -558,8 +558,8 @@ func (c *xlsxC) getCellDate(f *File, raw bool) (string, error) {
// intended to be used with for range on rows an argument with the spreadsheet // intended to be used with for range on rows an argument with the spreadsheet
// opened file. // opened file.
func (c *xlsxC) getValueFrom(f *File, d *xlsxSST, raw bool) (string, error) { func (c *xlsxC) getValueFrom(f *File, d *xlsxSST, raw bool) (string, error) {
f.Lock() f.mu.Lock()
defer f.Unlock() defer f.mu.Unlock()
switch c.T { switch c.T {
case "b": case "b":
return c.getCellBool(f, raw) return c.getCellBool(f, raw)
@ -600,13 +600,13 @@ func (f *File) SetCellDefault(sheet, cell, value string) error {
if err != nil { if err != nil {
return err return err
} }
c, col, row, err := f.prepareCell(ws, cell) c, col, row, err := ws.prepareCell(cell)
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
c.S = f.prepareCellStyle(ws, col, row, c.S) c.S = ws.prepareCellStyle(col, row, c.S)
c.setCellDefault(value) c.setCellDefault(value)
return f.removeFormula(c, ws, sheet) return f.removeFormula(c, ws, sheet)
} }
@ -718,7 +718,7 @@ func (f *File) SetCellFormula(sheet, cell, formula string, opts ...FormulaOpts)
if err != nil { if err != nil {
return err return err
} }
c, _, _, err := f.prepareCell(ws, cell) c, _, _, err := ws.prepareCell(cell)
if err != nil { if err != nil {
return err return err
} }
@ -763,7 +763,7 @@ func (ws *xlsxWorksheet) setSharedFormula(ref string) error {
cnt := ws.countSharedFormula() cnt := ws.countSharedFormula()
for c := coordinates[0]; c <= coordinates[2]; c++ { for c := coordinates[0]; c <= coordinates[2]; c++ {
for r := coordinates[1]; r <= coordinates[3]; r++ { for r := coordinates[1]; r <= coordinates[3]; r++ {
prepareSheetXML(ws, c, r) ws.prepareSheetXML(c, r)
cell := &ws.SheetData.Row[r-1].C[c-1] cell := &ws.SheetData.Row[r-1].C[c-1]
if cell.F == nil { if cell.F == nil {
cell.F = &xlsxF{} cell.F = &xlsxF{}
@ -867,7 +867,7 @@ func (f *File) SetCellHyperLink(sheet, cell, link, linkType string, opts ...Hype
if err != nil { if err != nil {
return err return err
} }
if cell, err = f.mergeCellsParser(ws, cell); err != nil { if cell, err = ws.mergeCellsParser(cell); err != nil {
return err return err
} }
@ -944,7 +944,7 @@ func (f *File) GetCellRichText(sheet, cell string) (runs []RichTextRun, err erro
if err != nil { if err != nil {
return return
} }
c, _, _, err := f.prepareCell(ws, cell) c, _, _, err := ws.prepareCell(cell)
if err != nil { if err != nil {
return return
} }
@ -1171,14 +1171,14 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
if err != nil { if err != nil {
return err return err
} }
c, col, row, err := f.prepareCell(ws, cell) c, col, row, err := ws.prepareCell(cell)
if err != nil { if err != nil {
return err return err
} }
if err := f.sharedStringsLoader(); err != nil { if err := f.sharedStringsLoader(); err != nil {
return err return err
} }
c.S = f.prepareCellStyle(ws, col, row, c.S) c.S = ws.prepareCellStyle(col, row, c.S)
si := xlsxSI{} si := xlsxSI{}
sst, err := f.sharedStringsReader() sst, err := f.sharedStringsReader()
if err != nil { if err != nil {
@ -1252,9 +1252,9 @@ func (f *File) setSheetCells(sheet, cell string, slice interface{}, dir adjustDi
} }
// getCellInfo does common preparation for all set cell value functions. // getCellInfo does common preparation for all set cell value functions.
func (f *File) prepareCell(ws *xlsxWorksheet, cell string) (*xlsxC, int, int, error) { func (ws *xlsxWorksheet) prepareCell(cell string) (*xlsxC, int, int, error) {
var err error var err error
cell, err = f.mergeCellsParser(ws, cell) cell, err = ws.mergeCellsParser(cell)
if err != nil { if err != nil {
return nil, 0, 0, err return nil, 0, 0, err
} }
@ -1263,9 +1263,9 @@ func (f *File) prepareCell(ws *xlsxWorksheet, cell string) (*xlsxC, int, int, er
return nil, 0, 0, err return nil, 0, 0, err
} }
prepareSheetXML(ws, col, row) ws.prepareSheetXML(col, row)
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
return &ws.SheetData.Row[row-1].C[col-1], col, row, err return &ws.SheetData.Row[row-1].C[col-1], col, row, err
} }
@ -1277,7 +1277,7 @@ func (f *File) getCellStringFunc(sheet, cell string, fn func(x *xlsxWorksheet, c
if err != nil { if err != nil {
return "", err return "", err
} }
cell, err = f.mergeCellsParser(ws, cell) cell, err = ws.mergeCellsParser(cell)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -1286,8 +1286,8 @@ func (f *File) getCellStringFunc(sheet, cell string, fn func(x *xlsxWorksheet, c
return "", err return "", err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
lastRowNum := 0 lastRowNum := 0
if l := len(ws.SheetData.Row); l > 0 { if l := len(ws.SheetData.Row); l > 0 {
@ -1366,7 +1366,7 @@ func (f *File) formattedValue(c *xlsxC, raw bool, cellType CellType) (string, er
// prepareCellStyle provides a function to prepare style index of cell in // prepareCellStyle provides a function to prepare style index of cell in
// worksheet by given column index and style index. // worksheet by given column index and style index.
func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, row, style int) int { func (ws *xlsxWorksheet) prepareCellStyle(col, row, style int) int {
if style != 0 { if style != 0 {
return style return style
} }
@ -1387,7 +1387,7 @@ func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, row, style int) int {
// mergeCellsParser provides a function to check merged cells in worksheet by // mergeCellsParser provides a function to check merged cells in worksheet by
// given cell reference. // given cell reference.
func (f *File) mergeCellsParser(ws *xlsxWorksheet, cell string) (string, error) { func (ws *xlsxWorksheet) mergeCellsParser(cell string) (string, error) {
cell = strings.ToUpper(cell) cell = strings.ToUpper(cell)
col, row, err := CellNameToCoordinates(cell) col, row, err := CellNameToCoordinates(cell)
if err != nil { if err != nil {

44
col.go
View File

@ -215,11 +215,11 @@ func (f *File) Cols(sheet string) (*Cols, error) {
if !ok { if !ok {
return nil, ErrSheetNotExist{sheet} return nil, ErrSheetNotExist{sheet}
} }
if ws, ok := f.Sheet.Load(name); ok && ws != nil { if worksheet, ok := f.Sheet.Load(name); ok && worksheet != nil {
worksheet := ws.(*xlsxWorksheet) ws := worksheet.(*xlsxWorksheet)
worksheet.Lock() ws.mu.Lock()
defer worksheet.Unlock() defer ws.mu.Unlock()
output, _ := xml.Marshal(worksheet) output, _ := xml.Marshal(ws)
f.saveFileList(name, f.replaceNameSpaceBytes(name, output)) f.saveFileList(name, f.replaceNameSpaceBytes(name, output))
} }
var colIterator columnXMLIterator var colIterator columnXMLIterator
@ -261,8 +261,8 @@ func (f *File) GetColVisible(sheet, col string) (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
if ws.Cols == nil { if ws.Cols == nil {
return true, err return true, err
} }
@ -295,8 +295,8 @@ func (f *File) SetColVisible(sheet, columns string, visible bool) error {
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
colData := xlsxCol{ colData := xlsxCol{
Min: min, Min: min,
Max: max, Max: max,
@ -432,17 +432,17 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {
if err != nil { if err != nil {
return err return err
} }
s.Lock() s.mu.Lock()
if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID { if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID {
s.Unlock() s.mu.Unlock()
return newInvalidStyleID(styleID) return newInvalidStyleID(styleID)
} }
s.Unlock() s.mu.Unlock()
ws, err := f.workSheetReader(sheet) ws, err := f.workSheetReader(sheet)
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
if ws.Cols == nil { if ws.Cols == nil {
ws.Cols = &xlsxCols{} ws.Cols = &xlsxCols{}
} }
@ -461,7 +461,7 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {
fc.Width = c.Width fc.Width = c.Width
return fc return fc
}) })
ws.Unlock() ws.mu.Unlock()
if rows := len(ws.SheetData.Row); rows > 0 { if rows := len(ws.SheetData.Row); rows > 0 {
for col := min; col <= max; col++ { for col := min; col <= max; col++ {
from, _ := CoordinatesToCellName(col, 1) from, _ := CoordinatesToCellName(col, 1)
@ -488,8 +488,8 @@ func (f *File) SetColWidth(sheet, startCol, endCol string, width float64) error
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
col := xlsxCol{ col := xlsxCol{
Min: min, Min: min,
Max: max, Max: max,
@ -634,8 +634,8 @@ func (f *File) positionObjectPixels(sheet string, col, row, x1, y1, width, heigh
// sheet name and column number. // sheet name and column number.
func (f *File) getColWidth(sheet string, col int) int { func (f *File) getColWidth(sheet string, col int) int {
ws, _ := f.workSheetReader(sheet) ws, _ := f.workSheetReader(sheet)
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
if ws.Cols != nil { if ws.Cols != nil {
var width float64 var width float64
for _, v := range ws.Cols.Col { for _, v := range ws.Cols.Col {
@ -663,8 +663,8 @@ func (f *File) GetColStyle(sheet, col string) (int, error) {
if err != nil { if err != nil {
return styleID, err return styleID, err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
if ws.Cols != nil { if ws.Cols != nil {
for _, v := range ws.Cols.Col { for _, v := range ws.Cols.Col {
if v.Min <= colNum && colNum <= v.Max { if v.Min <= colNum && colNum <= v.Max {
@ -686,8 +686,8 @@ func (f *File) GetColWidth(sheet, col string) (float64, error) {
if err != nil { if err != nil {
return defaultColWidth, err return defaultColWidth, err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
if ws.Cols != nil { if ws.Cols != nil {
var width float64 var width float64
for _, v := range ws.Cols.Col { for _, v := range ws.Cols.Col {

View File

@ -68,8 +68,8 @@ func (f *File) GetComments(sheet string) ([]Comment, error) {
func (f *File) getSheetComments(sheetFile string) string { func (f *File) getSheetComments(sheetFile string) string {
rels, _ := f.relsReader("xl/worksheets/_rels/" + sheetFile + ".rels") rels, _ := f.relsReader("xl/worksheets/_rels/" + sheetFile + ".rels")
if sheetRels := rels; sheetRels != nil { if sheetRels := rels; sheetRels != nil {
sheetRels.Lock() sheetRels.mu.Lock()
defer sheetRels.Unlock() defer sheetRels.mu.Unlock()
for _, v := range sheetRels.Relationships { for _, v := range sheetRels.Relationships {
if v.Type == SourceRelationshipComments { if v.Type == SourceRelationshipComments {
return v.Target return v.Target

View File

@ -1285,8 +1285,8 @@ func (f *File) drawingParser(path string) (*xlsxWsDr, int, error) {
if drawing, ok := f.Drawings.Load(path); ok && drawing != nil { if drawing, ok := f.Drawings.Load(path); ok && drawing != nil {
wsDr = drawing.(*xlsxWsDr) wsDr = drawing.(*xlsxWsDr)
} }
wsDr.Lock() wsDr.mu.Lock()
defer wsDr.Unlock() defer wsDr.mu.Unlock()
return wsDr, len(wsDr.OneCellAnchor) + len(wsDr.TwoCellAnchor) + 2, nil return wsDr, len(wsDr.OneCellAnchor) + len(wsDr.TwoCellAnchor) + 2, nil
} }

View File

@ -28,7 +28,7 @@ import (
// File define a populated spreadsheet file struct. // File define a populated spreadsheet file struct.
type File struct { type File struct {
sync.Mutex mu sync.Mutex
options *Options options *Options
xmlAttr map[string][]xml.Attr xmlAttr map[string][]xml.Attr
checked map[string]bool checked map[string]bool
@ -234,8 +234,8 @@ func (f *File) setDefaultTimeStyle(sheet, cell string, format int) error {
// workSheetReader provides a function to get the pointer to the structure // workSheetReader provides a function to get the pointer to the structure
// after deserialization by given worksheet name. // after deserialization by given worksheet name.
func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) { func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
f.Lock() f.mu.Lock()
defer f.Unlock() defer f.mu.Unlock()
var ( var (
name string name string
ok bool ok bool
@ -271,8 +271,8 @@ func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
f.checked = make(map[string]bool) f.checked = make(map[string]bool)
} }
if ok = f.checked[name]; !ok { if ok = f.checked[name]; !ok {
checkSheet(ws) ws.checkSheet()
if err = checkRow(ws); err != nil { if err = ws.checkRow(); err != nil {
return return
} }
f.checked[name] = true f.checked[name] = true
@ -283,7 +283,7 @@ func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
// checkSheet provides a function to fill each row element and make that is // checkSheet provides a function to fill each row element and make that is
// continuous in a worksheet of XML. // continuous in a worksheet of XML.
func checkSheet(ws *xlsxWorksheet) { func (ws *xlsxWorksheet) checkSheet() {
var row int var row int
var r0 xlsxRow var r0 xlsxRow
for i, r := range ws.SheetData.Row { for i, r := range ws.SheetData.Row {
@ -319,13 +319,13 @@ func checkSheet(ws *xlsxWorksheet) {
for i := 1; i <= row; i++ { for i := 1; i <= row; i++ {
sheetData.Row[i-1].R = i sheetData.Row[i-1].R = i
} }
checkSheetR0(ws, &sheetData, &r0) ws.checkSheetR0(&sheetData, &r0)
} }
// checkSheetR0 handle the row element with r="0" attribute, cells in this row // checkSheetR0 handle the row element with r="0" attribute, cells in this row
// could be disorderly, the cell in this row can be used as the value of // could be disorderly, the cell in this row can be used as the value of
// which cell is empty in the normal rows. // which cell is empty in the normal rows.
func checkSheetR0(ws *xlsxWorksheet, sheetData *xlsxSheetData, r0 *xlsxRow) { func (ws *xlsxWorksheet) checkSheetR0(sheetData *xlsxSheetData, r0 *xlsxRow) {
for _, cell := range r0.C { for _, cell := range r0.C {
if col, row, err := CellNameToCoordinates(cell.R); err == nil { if col, row, err := CellNameToCoordinates(cell.R); err == nil {
rows, rowIdx := len(sheetData.Row), row-1 rows, rowIdx := len(sheetData.Row), row-1
@ -351,8 +351,8 @@ func (f *File) setRels(rID, relPath, relType, target, targetMode string) int {
if rels == nil || rID == "" { if rels == nil || rID == "" {
return f.addRels(relPath, relType, target, targetMode) return f.addRels(relPath, relType, target, targetMode)
} }
rels.Lock() rels.mu.Lock()
defer rels.Unlock() defer rels.mu.Unlock()
var ID int var ID int
for i, rel := range rels.Relationships { for i, rel := range rels.Relationships {
if rel.ID == rID { if rel.ID == rID {
@ -376,8 +376,8 @@ func (f *File) addRels(relPath, relType, target, targetMode string) int {
if rels == nil { if rels == nil {
rels = &xlsxRelationships{} rels = &xlsxRelationships{}
} }
rels.Lock() rels.mu.Lock()
defer rels.Unlock() defer rels.mu.Unlock()
var rID int var rID int
for idx, rel := range rels.Relationships { for idx, rel := range rels.Relationships {
ID, _ := strconv.Atoi(strings.TrimPrefix(rel.ID, "rId")) ID, _ := strconv.Atoi(strings.TrimPrefix(rel.ID, "rId"))
@ -490,8 +490,8 @@ func (f *File) AddVBAProject(file []byte) error {
if err != nil { if err != nil {
return err return err
} }
rels.Lock() rels.mu.Lock()
defer rels.Unlock() defer rels.mu.Unlock()
var rID int var rID int
var ok bool var ok bool
for _, rel := range rels.Relationships { for _, rel := range rels.Relationships {
@ -524,8 +524,8 @@ func (f *File) setContentTypePartProjectExtensions(contentType string) error {
if err != nil { if err != nil {
return err return err
} }
content.Lock() content.mu.Lock()
defer content.Unlock() defer content.mu.Unlock()
for _, v := range content.Defaults { for _, v := range content.Defaults {
if v.Extension == "bin" { if v.Extension == "bin" {
ok = true ok = true

View File

@ -64,8 +64,8 @@ func (f *File) MergeCell(sheet, hCell, vCell string) error {
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
ref := hCell + ":" + vCell ref := hCell + ":" + vCell
if ws.MergeCells != nil { if ws.MergeCells != nil {
ws.MergeCells.Cells = append(ws.MergeCells.Cells, &xlsxMergeCell{Ref: ref, rect: rect}) ws.MergeCells.Cells = append(ws.MergeCells.Cells, &xlsxMergeCell{Ref: ref, rect: rect})
@ -87,8 +87,8 @@ func (f *File) UnmergeCell(sheet, hCell, vCell string) error {
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
rect1, err := rangeRefToCoordinates(hCell + ":" + vCell) rect1, err := rangeRefToCoordinates(hCell + ":" + vCell)
if err != nil { if err != nil {
return err return err

View File

@ -207,7 +207,7 @@ func TestFlatMergedCells(t *testing.T) {
} }
func TestMergeCellsParser(t *testing.T) { func TestMergeCellsParser(t *testing.T) {
f := NewFile() ws := &xlsxWorksheet{MergeCells: &xlsxMergeCells{Cells: []*xlsxMergeCell{nil}}}
_, err := f.mergeCellsParser(&xlsxWorksheet{MergeCells: &xlsxMergeCells{Cells: []*xlsxMergeCell{nil}}}, "A1") _, err := ws.mergeCellsParser("A1")
assert.NoError(t, err) assert.NoError(t, err)
} }

View File

@ -216,7 +216,7 @@ func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error {
if err != nil { if err != nil {
return err return err
} }
ws.Lock() ws.mu.Lock()
// Add first picture for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder. // Add first picture for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder.
drawingID := f.countDrawings() + 1 drawingID := f.countDrawings() + 1
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml" drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
@ -231,7 +231,7 @@ func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error {
} }
drawingHyperlinkRID = f.addRels(drawingRels, SourceRelationshipHyperLink, options.Hyperlink, hyperlinkType) drawingHyperlinkRID = f.addRels(drawingRels, SourceRelationshipHyperLink, options.Hyperlink, hyperlinkType)
} }
ws.Unlock() ws.mu.Unlock()
err = f.addDrawingPicture(sheet, drawingXML, cell, ext, drawingRID, drawingHyperlinkRID, img, options) err = f.addDrawingPicture(sheet, drawingXML, cell, ext, drawingRID, drawingHyperlinkRID, img, options)
if err != nil { if err != nil {
return err return err
@ -256,8 +256,8 @@ func (f *File) deleteSheetRelationships(sheet, rID string) {
if sheetRels == nil { if sheetRels == nil {
sheetRels = &xlsxRelationships{} sheetRels = &xlsxRelationships{}
} }
sheetRels.Lock() sheetRels.mu.Lock()
defer sheetRels.Unlock() defer sheetRels.mu.Unlock()
for k, v := range sheetRels.Relationships { for k, v := range sheetRels.Relationships {
if v.ID == rID { if v.ID == rID {
sheetRels.Relationships = append(sheetRels.Relationships[:k], sheetRels.Relationships[k+1:]...) sheetRels.Relationships = append(sheetRels.Relationships[:k], sheetRels.Relationships[k+1:]...)
@ -391,8 +391,8 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, ext string, rID, hyper
FLocksWithSheet: *opts.Locked, FLocksWithSheet: *opts.Locked,
FPrintsWithSheet: *opts.PrintObject, FPrintsWithSheet: *opts.PrintObject,
} }
content.Lock() content.mu.Lock()
defer content.Unlock() defer content.mu.Unlock()
content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor) content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
f.Drawings.Store(drawingXML, content) f.Drawings.Store(drawingXML, content)
return err return err
@ -447,8 +447,8 @@ func (f *File) setContentTypePartImageExtensions() error {
if err != nil { if err != nil {
return err return err
} }
content.Lock() content.mu.Lock()
defer content.Unlock() defer content.mu.Unlock()
for _, file := range content.Defaults { for _, file := range content.Defaults {
delete(imageTypes, file.Extension) delete(imageTypes, file.Extension)
} }
@ -469,8 +469,8 @@ func (f *File) setContentTypePartVMLExtensions() error {
if err != nil { if err != nil {
return err return err
} }
content.Lock() content.mu.Lock()
defer content.Unlock() defer content.mu.Unlock()
for _, v := range content.Defaults { for _, v := range content.Defaults {
if v.Extension == "vml" { if v.Extension == "vml" {
vml = true vml = true
@ -522,8 +522,8 @@ func (f *File) addContentTypePart(index int, contentType string) error {
if err != nil { if err != nil {
return err return err
} }
content.Lock() content.mu.Lock()
defer content.Unlock() defer content.mu.Unlock()
for _, v := range content.Overrides { for _, v := range content.Overrides {
if v.PartName == partNames[contentType] { if v.PartName == partNames[contentType] {
return err return err
@ -549,8 +549,8 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
if sheetRels == nil { if sheetRels == nil {
sheetRels = &xlsxRelationships{} sheetRels = &xlsxRelationships{}
} }
sheetRels.Lock() sheetRels.mu.Lock()
defer sheetRels.Unlock() defer sheetRels.mu.Unlock()
for _, v := range sheetRels.Relationships { for _, v := range sheetRels.Relationships {
if v.ID == rID { if v.ID == rID {
return v.Target return v.Target
@ -683,8 +683,8 @@ func (f *File) getPicturesFromWsDr(row, col int, drawingRelationships string, ws
anchor *xdrCellAnchor anchor *xdrCellAnchor
drawRel *xlsxRelationship drawRel *xlsxRelationship
) )
wsDr.Lock() wsDr.mu.Lock()
defer wsDr.Unlock() defer wsDr.mu.Unlock()
for _, anchor = range wsDr.TwoCellAnchor { for _, anchor = range wsDr.TwoCellAnchor {
if anchor.From != nil && anchor.Pic != nil { if anchor.From != nil && anchor.Pic != nil {
if anchor.From.Col == col && anchor.From.Row == row { if anchor.From.Col == col && anchor.From.Row == row {
@ -710,8 +710,8 @@ func (f *File) getPicturesFromWsDr(row, col int, drawingRelationships string, ws
// relationship ID. // relationship ID.
func (f *File) getDrawingRelationships(rels, rID string) *xlsxRelationship { func (f *File) getDrawingRelationships(rels, rID string) *xlsxRelationship {
if drawingRels, _ := f.relsReader(rels); drawingRels != nil { if drawingRels, _ := f.relsReader(rels); drawingRels != nil {
drawingRels.Lock() drawingRels.mu.Lock()
defer drawingRels.Unlock() defer drawingRels.mu.Unlock()
for _, v := range drawingRels.Relationships { for _, v := range drawingRels.Relationships {
if v.ID == rID { if v.ID == rID {
return &v return &v

32
rows.go
View File

@ -267,12 +267,12 @@ func (f *File) Rows(sheet string) (*Rows, error) {
if !ok { if !ok {
return nil, ErrSheetNotExist{sheet} return nil, ErrSheetNotExist{sheet}
} }
if ws, ok := f.Sheet.Load(name); ok && ws != nil { if worksheet, ok := f.Sheet.Load(name); ok && worksheet != nil {
worksheet := ws.(*xlsxWorksheet) ws := worksheet.(*xlsxWorksheet)
worksheet.Lock() ws.mu.Lock()
defer worksheet.Unlock() defer ws.mu.Unlock()
// Flush data // Flush data
output, _ := xml.Marshal(worksheet) output, _ := xml.Marshal(ws)
f.saveFileList(name, f.replaceNameSpaceBytes(name, output)) f.saveFileList(name, f.replaceNameSpaceBytes(name, output))
} }
var err error var err error
@ -360,7 +360,7 @@ func (f *File) SetRowHeight(sheet string, row int, height float64) error {
return err return err
} }
prepareSheetXML(ws, 0, row) ws.prepareSheetXML(0, row)
rowIdx := row - 1 rowIdx := row - 1
ws.SheetData.Row[rowIdx].Ht = float64Ptr(height) ws.SheetData.Row[rowIdx].Ht = float64Ptr(height)
@ -372,8 +372,8 @@ func (f *File) SetRowHeight(sheet string, row int, height float64) error {
// name and row number. // name and row number.
func (f *File) getRowHeight(sheet string, row int) int { func (f *File) getRowHeight(sheet string, row int) int {
ws, _ := f.workSheetReader(sheet) ws, _ := f.workSheetReader(sheet)
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
for i := range ws.SheetData.Row { for i := range ws.SheetData.Row {
v := &ws.SheetData.Row[i] v := &ws.SheetData.Row[i]
if v.R == row && v.Ht != nil { if v.R == row && v.Ht != nil {
@ -416,8 +416,8 @@ func (f *File) GetRowHeight(sheet string, row int) (float64, error) {
// after deserialization of xl/sharedStrings.xml. // after deserialization of xl/sharedStrings.xml.
func (f *File) sharedStringsReader() (*xlsxSST, error) { func (f *File) sharedStringsReader() (*xlsxSST, error) {
var err error var err error
f.Lock() f.mu.Lock()
defer f.Unlock() defer f.mu.Unlock()
relPath := f.getWorkbookRelsPath() relPath := f.getWorkbookRelsPath()
if f.SharedStrings == nil { if f.SharedStrings == nil {
var sharedStrings xlsxSST var sharedStrings xlsxSST
@ -470,7 +470,7 @@ func (f *File) SetRowVisible(sheet string, row int, visible bool) error {
if err != nil { if err != nil {
return err return err
} }
prepareSheetXML(ws, 0, row) ws.prepareSheetXML(0, row)
ws.SheetData.Row[row-1].Hidden = !visible ws.SheetData.Row[row-1].Hidden = !visible
return nil return nil
} }
@ -511,7 +511,7 @@ func (f *File) SetRowOutlineLevel(sheet string, row int, level uint8) error {
if err != nil { if err != nil {
return err return err
} }
prepareSheetXML(ws, 0, row) ws.prepareSheetXML(0, row)
ws.SheetData.Row[row-1].OutlineLevel = level ws.SheetData.Row[row-1].OutlineLevel = level
return nil return nil
} }
@ -724,7 +724,7 @@ func (f *File) duplicateMergeCells(sheet string, ws *xlsxWorksheet, row, row2 in
// //
// Notice: this method could be very slow for large spreadsheets (more than // Notice: this method could be very slow for large spreadsheets (more than
// 3000 rows one sheet). // 3000 rows one sheet).
func checkRow(ws *xlsxWorksheet) error { func (ws *xlsxWorksheet) checkRow() error {
for rowIdx := range ws.SheetData.Row { for rowIdx := range ws.SheetData.Row {
rowData := &ws.SheetData.Row[rowIdx] rowData := &ws.SheetData.Row[rowIdx]
@ -814,8 +814,8 @@ func (f *File) SetRowStyle(sheet string, start, end, styleID int) error {
if err != nil { if err != nil {
return err return err
} }
s.Lock() s.mu.Lock()
defer s.Unlock() defer s.mu.Unlock()
if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID { if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID {
return newInvalidStyleID(styleID) return newInvalidStyleID(styleID)
} }
@ -823,7 +823,7 @@ func (f *File) SetRowStyle(sheet string, start, end, styleID int) error {
if err != nil { if err != nil {
return err return err
} }
prepareSheetXML(ws, 0, end) ws.prepareSheetXML(0, end)
for row := start - 1; row < end; row++ { for row := start - 1; row < end; row++ {
ws.SheetData.Row[row].S = styleID ws.SheetData.Row[row].S = styleID
ws.SheetData.Row[row].CustomFormat = true ws.SheetData.Row[row].CustomFormat = true

View File

@ -70,8 +70,8 @@ func (f *File) NewSheet(sheet string) (int, error) {
func (f *File) contentTypesReader() (*xlsxTypes, error) { func (f *File) contentTypesReader() (*xlsxTypes, error) {
if f.ContentTypes == nil { if f.ContentTypes == nil {
f.ContentTypes = new(xlsxTypes) f.ContentTypes = new(xlsxTypes)
f.ContentTypes.Lock() f.ContentTypes.mu.Lock()
defer f.ContentTypes.Unlock() defer f.ContentTypes.mu.Unlock()
if err := f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathContentTypes)))). if err := f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathContentTypes)))).
Decode(f.ContentTypes); err != nil && err != io.EOF { Decode(f.ContentTypes); err != nil && err != io.EOF {
return f.ContentTypes, err return f.ContentTypes, err
@ -217,8 +217,8 @@ func (f *File) setContentTypes(partName, contentType string) error {
if err != nil { if err != nil {
return err return err
} }
content.Lock() content.mu.Lock()
defer content.Unlock() defer content.mu.Unlock()
content.Overrides = append(content.Overrides, xlsxOverride{ content.Overrides = append(content.Overrides, xlsxOverride{
PartName: partName, PartName: partName,
ContentType: contentType, ContentType: contentType,
@ -615,8 +615,8 @@ func deleteAndAdjustDefinedNames(wb *xlsxWorkbook, deleteLocalSheetID int) {
// relationships by given relationships ID in the file workbook.xml.rels. // relationships by given relationships ID in the file workbook.xml.rels.
func (f *File) deleteSheetFromWorkbookRels(rID string) string { func (f *File) deleteSheetFromWorkbookRels(rID string) string {
rels, _ := f.relsReader(f.getWorkbookRelsPath()) rels, _ := f.relsReader(f.getWorkbookRelsPath())
rels.Lock() rels.mu.Lock()
defer rels.Unlock() defer rels.mu.Unlock()
for k, v := range rels.Relationships { for k, v := range rels.Relationships {
if v.ID == rID { if v.ID == rID {
rels.Relationships = append(rels.Relationships[:k], rels.Relationships[k+1:]...) rels.Relationships = append(rels.Relationships[:k], rels.Relationships[k+1:]...)
@ -636,8 +636,8 @@ func (f *File) deleteSheetFromContentTypes(target string) error {
if err != nil { if err != nil {
return err return err
} }
content.Lock() content.mu.Lock()
defer content.Unlock() defer content.mu.Unlock()
for k, v := range content.Overrides { for k, v := range content.Overrides {
if v.PartName == target { if v.PartName == target {
content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...) content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...)
@ -1842,9 +1842,9 @@ func (f *File) relsReader(path string) (*xlsxRelationships, error) {
// fillSheetData ensures there are enough rows, and columns in the chosen // fillSheetData ensures there are enough rows, and columns in the chosen
// row to accept data. Missing rows are backfilled and given their row number // row to accept data. Missing rows are backfilled and given their row number
// Uses the last populated row as a hint for the size of the next row to add // Uses the last populated row as a hint for the size of the next row to add
func prepareSheetXML(ws *xlsxWorksheet, col int, row int) { func (ws *xlsxWorksheet) prepareSheetXML(col int, row int) {
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
rowCount := len(ws.SheetData.Row) rowCount := len(ws.SheetData.Row)
sizeHint := 0 sizeHint := 0
var ht *float64 var ht *float64
@ -1879,8 +1879,8 @@ func fillColumns(rowData *xlsxRow, col, row int) {
// makeContiguousColumns make columns in specific rows as contiguous. // makeContiguousColumns make columns in specific rows as contiguous.
func makeContiguousColumns(ws *xlsxWorksheet, fromRow, toRow, colCount int) { func makeContiguousColumns(ws *xlsxWorksheet, fromRow, toRow, colCount int) {
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
for ; fromRow < toRow; fromRow++ { for ; fromRow < toRow; fromRow++ {
rowData := &ws.SheetData.Row[fromRow-1] rowData := &ws.SheetData.Row[fromRow-1]
fillColumns(rowData, colCount, fromRow) fillColumns(rowData, colCount, fromRow)

View File

@ -2008,8 +2008,8 @@ func (f *File) NewStyle(style *Style) (int, error) {
if err != nil { if err != nil {
return cellXfsID, err return cellXfsID, err
} }
s.Lock() s.mu.Lock()
defer s.Unlock() defer s.mu.Unlock()
// check given style already exist. // check given style already exist.
if cellXfsID, err = f.getStyleID(s, fs); err != nil || cellXfsID != -1 { if cellXfsID, err = f.getStyleID(s, fs); err != nil || cellXfsID != -1 {
return cellXfsID, err return cellXfsID, err
@ -2669,10 +2669,10 @@ func (f *File) GetCellStyle(sheet, cell string) (int, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
prepareSheetXML(ws, col, row) ws.prepareSheetXML(col, row)
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
return f.prepareCellStyle(ws, col, row, ws.SheetData.Row[row-1].C[col-1].S), err return ws.prepareCellStyle(col, row, ws.SheetData.Row[row-1].C[col-1].S), err
} }
// SetCellStyle provides a function to add style attribute for cells by given // SetCellStyle provides a function to add style attribute for cells by given
@ -2808,17 +2808,17 @@ func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error {
if err != nil { if err != nil {
return err return err
} }
prepareSheetXML(ws, vCol, vRow) ws.prepareSheetXML(vCol, vRow)
makeContiguousColumns(ws, hRow, vRow, vCol) makeContiguousColumns(ws, hRow, vRow, vCol)
ws.Lock() ws.mu.Lock()
defer ws.Unlock() defer ws.mu.Unlock()
s, err := f.stylesReader() s, err := f.stylesReader()
if err != nil { if err != nil {
return err return err
} }
s.Lock() s.mu.Lock()
defer s.Unlock() defer s.mu.Unlock()
if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID { if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID {
return newInvalidStyleID(styleID) return newInvalidStyleID(styleID)
} }

View File

@ -145,8 +145,8 @@ func (f *File) setWorkbook(name string, sheetID, rid int) {
// the spreadsheet. // the spreadsheet.
func (f *File) getWorkbookPath() (path string) { func (f *File) getWorkbookPath() (path string) {
if rels, _ := f.relsReader("_rels/.rels"); rels != nil { if rels, _ := f.relsReader("_rels/.rels"); rels != nil {
rels.Lock() rels.mu.Lock()
defer rels.Unlock() defer rels.mu.Unlock()
for _, rel := range rels.Relationships { for _, rel := range rels.Relationships {
if rel.Type == SourceRelationshipOfficeDocument { if rel.Type == SourceRelationshipOfficeDocument {
path = strings.TrimPrefix(rel.Target, "/") path = strings.TrimPrefix(rel.Target, "/")

View File

@ -20,7 +20,7 @@ import (
// parts, it takes a Multipurpose Internet Mail Extension (MIME) media type as a // parts, it takes a Multipurpose Internet Mail Extension (MIME) media type as a
// value. // value.
type xlsxTypes struct { type xlsxTypes struct {
sync.Mutex mu sync.Mutex
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/content-types Types"` XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/content-types Types"`
Defaults []xlsxDefault `xml:"Default"` Defaults []xlsxDefault `xml:"Default"`
Overrides []xlsxOverride `xml:"Override"` Overrides []xlsxOverride `xml:"Override"`

View File

@ -440,7 +440,7 @@ type xlsxPoint2D struct {
// xlsxWsDr directly maps the root element for a part of this content type shall // xlsxWsDr directly maps the root element for a part of this content type shall
// wsDr. // wsDr.
type xlsxWsDr struct { type xlsxWsDr struct {
sync.Mutex mu sync.Mutex
XMLName xml.Name `xml:"xdr:wsDr"` XMLName xml.Name `xml:"xdr:wsDr"`
A string `xml:"xmlns:a,attr,omitempty"` A string `xml:"xmlns:a,attr,omitempty"`
Xdr string `xml:"xmlns:xdr,attr,omitempty"` Xdr string `xml:"xmlns:xdr,attr,omitempty"`

View File

@ -18,7 +18,7 @@ import (
// xlsxStyleSheet is the root element of the Styles part. // xlsxStyleSheet is the root element of the Styles part.
type xlsxStyleSheet struct { type xlsxStyleSheet struct {
sync.Mutex mu sync.Mutex
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main styleSheet"` XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main styleSheet"`
NumFmts *xlsxNumFmts `xml:"numFmts"` NumFmts *xlsxNumFmts `xml:"numFmts"`
Fonts *xlsxFonts `xml:"fonts"` Fonts *xlsxFonts `xml:"fonts"`

View File

@ -18,7 +18,7 @@ import (
// xlsxRelationships describe references from parts to other internal resources in the package or to external resources. // xlsxRelationships describe references from parts to other internal resources in the package or to external resources.
type xlsxRelationships struct { type xlsxRelationships struct {
sync.Mutex mu sync.Mutex
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"` XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"`
Relationships []xlsxRelationship `xml:"Relationship"` Relationships []xlsxRelationship `xml:"Relationship"`
} }

View File

@ -19,7 +19,7 @@ import (
// xlsxWorksheet directly maps the worksheet element in the namespace // xlsxWorksheet directly maps the worksheet element in the namespace
// http://schemas.openxmlformats.org/spreadsheetml/2006/main. // http://schemas.openxmlformats.org/spreadsheetml/2006/main.
type xlsxWorksheet struct { type xlsxWorksheet struct {
sync.Mutex mu sync.Mutex
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main worksheet"` XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main worksheet"`
SheetPr *xlsxSheetPr `xml:"sheetPr"` SheetPr *xlsxSheetPr `xml:"sheetPr"`
Dimension *xlsxDimension `xml:"dimension"` Dimension *xlsxDimension `xml:"dimension"`