- Avoid format text cell value as a numeric - Fix race conditions for concurrency safety functions
This commit is contained in:
parent
93c72b4d55
commit
612f6f104c
39
cell.go
39
cell.go
|
@ -288,16 +288,19 @@ func setCellDuration(value time.Duration) (t string, v string) {
|
||||||
// SetCellInt provides a function to set int type value of a cell by given
|
// SetCellInt provides a function to set int type value of a cell by given
|
||||||
// worksheet name, cell reference and cell value.
|
// worksheet name, cell reference and cell value.
|
||||||
func (f *File) SetCellInt(sheet, cell string, value int) error {
|
func (f *File) SetCellInt(sheet, cell string, value int) error {
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
|
ws.mu.Lock()
|
||||||
|
defer ws.mu.Unlock()
|
||||||
c, col, row, err := ws.prepareCell(cell)
|
c, col, row, err := ws.prepareCell(cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.mu.Lock()
|
|
||||||
defer ws.mu.Unlock()
|
|
||||||
c.S = ws.prepareCellStyle(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
|
||||||
|
@ -314,16 +317,19 @@ func setCellInt(value int) (t string, v string) {
|
||||||
// SetCellBool provides a function to set bool type value of a cell by given
|
// SetCellBool provides a function to set bool type value of a cell by given
|
||||||
// worksheet name, cell reference and cell value.
|
// worksheet name, cell reference and cell value.
|
||||||
func (f *File) SetCellBool(sheet, cell string, value bool) error {
|
func (f *File) SetCellBool(sheet, cell string, value bool) error {
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
|
ws.mu.Lock()
|
||||||
|
defer ws.mu.Unlock()
|
||||||
c, col, row, err := ws.prepareCell(cell)
|
c, col, row, err := ws.prepareCell(cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.mu.Lock()
|
|
||||||
defer ws.mu.Unlock()
|
|
||||||
c.S = ws.prepareCellStyle(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
|
||||||
|
@ -351,16 +357,19 @@ func setCellBool(value bool) (t string, v string) {
|
||||||
// var x float32 = 1.325
|
// var x float32 = 1.325
|
||||||
// f.SetCellFloat("Sheet1", "A1", float64(x), 2, 32)
|
// f.SetCellFloat("Sheet1", "A1", float64(x), 2, 32)
|
||||||
func (f *File) SetCellFloat(sheet, cell string, value float64, precision, bitSize int) error {
|
func (f *File) SetCellFloat(sheet, cell string, value float64, precision, bitSize int) error {
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
|
ws.mu.Lock()
|
||||||
|
defer ws.mu.Unlock()
|
||||||
c, col, row, err := ws.prepareCell(cell)
|
c, col, row, err := ws.prepareCell(cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.mu.Lock()
|
|
||||||
defer ws.mu.Unlock()
|
|
||||||
c.S = ws.prepareCellStyle(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
|
||||||
|
@ -377,16 +386,19 @@ func setCellFloat(value float64, precision, bitSize int) (t string, v string) {
|
||||||
// SetCellStr provides a function to set string type value of a cell. Total
|
// SetCellStr provides a function to set string type value of a cell. Total
|
||||||
// number of characters that a cell can contain 32767 characters.
|
// number of characters that a cell can contain 32767 characters.
|
||||||
func (f *File) SetCellStr(sheet, cell, value string) error {
|
func (f *File) SetCellStr(sheet, cell, value string) error {
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
|
ws.mu.Lock()
|
||||||
|
defer ws.mu.Unlock()
|
||||||
c, col, row, err := ws.prepareCell(cell)
|
c, col, row, err := ws.prepareCell(cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.mu.Lock()
|
|
||||||
defer ws.mu.Unlock()
|
|
||||||
c.S = ws.prepareCellStyle(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
|
||||||
|
@ -558,8 +570,6 @@ 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.mu.Lock()
|
|
||||||
defer f.mu.Unlock()
|
|
||||||
switch c.T {
|
switch c.T {
|
||||||
case "b":
|
case "b":
|
||||||
return c.getCellBool(f, raw)
|
return c.getCellBool(f, raw)
|
||||||
|
@ -596,16 +606,19 @@ func (c *xlsxC) getValueFrom(f *File, d *xlsxSST, raw bool) (string, error) {
|
||||||
// SetCellDefault provides a function to set string type value of a cell as
|
// SetCellDefault provides a function to set string type value of a cell as
|
||||||
// default format without escaping the cell.
|
// default format without escaping the cell.
|
||||||
func (f *File) SetCellDefault(sheet, cell, value string) error {
|
func (f *File) SetCellDefault(sheet, cell, value string) error {
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
|
ws.mu.Lock()
|
||||||
|
defer ws.mu.Unlock()
|
||||||
c, col, row, err := ws.prepareCell(cell)
|
c, col, row, err := ws.prepareCell(cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.mu.Lock()
|
|
||||||
defer ws.mu.Unlock()
|
|
||||||
c.S = ws.prepareCellStyle(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)
|
||||||
|
@ -1264,8 +1277,6 @@ func (ws *xlsxWorksheet) prepareCell(cell string) (*xlsxC, int, int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.prepareSheetXML(col, row)
|
ws.prepareSheetXML(col, row)
|
||||||
ws.mu.Lock()
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ func TestConcurrency(t *testing.T) {
|
||||||
// Concurrency iterate columns
|
// Concurrency iterate columns
|
||||||
cols, err := f.Cols("Sheet1")
|
cols, err := f.Cols("Sheet1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
for rows.Next() {
|
for cols.Next() {
|
||||||
_, err := cols.Rows()
|
_, err := cols.Rows()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
24
col.go
24
col.go
|
@ -257,10 +257,13 @@ func (f *File) GetColVisible(sheet, col string) (bool, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
ws.mu.Lock()
|
ws.mu.Lock()
|
||||||
defer ws.mu.Unlock()
|
defer ws.mu.Unlock()
|
||||||
if ws.Cols == nil {
|
if ws.Cols == nil {
|
||||||
|
@ -428,20 +431,24 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
f.mu.Lock()
|
||||||
s, err := f.stylesReader()
|
s, err := f.stylesReader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
ws, err := f.workSheetReader(sheet)
|
||||||
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
s.mu.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.mu.Unlock()
|
s.mu.Unlock()
|
||||||
return newInvalidStyleID(styleID)
|
return newInvalidStyleID(styleID)
|
||||||
}
|
}
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ws.mu.Lock()
|
ws.mu.Lock()
|
||||||
if ws.Cols == nil {
|
if ws.Cols == nil {
|
||||||
ws.Cols = &xlsxCols{}
|
ws.Cols = &xlsxCols{}
|
||||||
|
@ -484,10 +491,13 @@ func (f *File) SetColWidth(sheet, startCol, endCol string, width float64) error
|
||||||
if width > MaxColumnWidth {
|
if width > MaxColumnWidth {
|
||||||
return ErrColumnWidth
|
return ErrColumnWidth
|
||||||
}
|
}
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
ws.mu.Lock()
|
ws.mu.Lock()
|
||||||
defer ws.mu.Unlock()
|
defer ws.mu.Unlock()
|
||||||
col := xlsxCol{
|
col := xlsxCol{
|
||||||
|
@ -659,10 +669,13 @@ func (f *File) GetColStyle(sheet, col string) (int, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return styleID, err
|
return styleID, err
|
||||||
}
|
}
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return styleID, err
|
return styleID, err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
ws.mu.Lock()
|
ws.mu.Lock()
|
||||||
defer ws.mu.Unlock()
|
defer ws.mu.Unlock()
|
||||||
if ws.Cols != nil {
|
if ws.Cols != nil {
|
||||||
|
@ -682,10 +695,13 @@ func (f *File) GetColWidth(sheet, col string) (float64, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return defaultColWidth, err
|
return defaultColWidth, err
|
||||||
}
|
}
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return defaultColWidth, err
|
return defaultColWidth, err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
ws.mu.Lock()
|
ws.mu.Lock()
|
||||||
defer ws.mu.Unlock()
|
defer ws.mu.Unlock()
|
||||||
if ws.Cols != nil {
|
if ws.Cols != nil {
|
||||||
|
|
|
@ -234,8 +234,6 @@ 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.mu.Lock()
|
|
||||||
defer f.mu.Unlock()
|
|
||||||
var (
|
var (
|
||||||
name string
|
name string
|
||||||
ok bool
|
ok bool
|
||||||
|
|
|
@ -948,10 +948,13 @@ func (nf *numberFormat) zeroHandler() string {
|
||||||
// textHandler will be handling text selection for a number format expression.
|
// textHandler will be handling text selection for a number format expression.
|
||||||
func (nf *numberFormat) textHandler() (result string) {
|
func (nf *numberFormat) textHandler() (result string) {
|
||||||
for _, token := range nf.section[nf.sectionIdx].Items {
|
for _, token := range nf.section[nf.sectionIdx].Items {
|
||||||
|
if inStrSlice([]string{nfp.TokenTypeDateTimes, nfp.TokenTypeElapsedDateTimes}, token.TType, false) != -1 {
|
||||||
|
return nf.value
|
||||||
|
}
|
||||||
if token.TType == nfp.TokenTypeLiteral {
|
if token.TType == nfp.TokenTypeLiteral {
|
||||||
result += token.TValue
|
result += token.TValue
|
||||||
}
|
}
|
||||||
if token.TType == nfp.TokenTypeTextPlaceHolder || token.TType == nfp.TokenTypeZeroPlaceHolder {
|
if token.TType == nfp.TokenTypeGeneral || token.TType == nfp.TokenTypeTextPlaceHolder || token.TType == nfp.TokenTypeZeroPlaceHolder {
|
||||||
result += nf.value
|
result += nf.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1008,4 +1008,12 @@ func TestNumFmt(t *testing.T) {
|
||||||
result := format(item[0], item[1], false, CellTypeNumber)
|
result := format(item[0], item[1], false, CellTypeNumber)
|
||||||
assert.Equal(t, item[2], result, item)
|
assert.Equal(t, item[2], result, item)
|
||||||
}
|
}
|
||||||
|
for _, item := range [][]string{
|
||||||
|
{"1234.5678", "General", "1234.5678"},
|
||||||
|
{"1234.5678", "yyyy\"年\"m\"月\"d\"日\";@", "1234.5678"},
|
||||||
|
{"1234.5678", "0_);[Red]\\(0\\)", "1234.5678"},
|
||||||
|
} {
|
||||||
|
result := format(item[0], item[1], false, CellTypeSharedString)
|
||||||
|
assert.Equal(t, item[2], result, item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,10 +212,13 @@ func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Read sheet data.
|
// Read sheet data.
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
ws.mu.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
|
||||||
|
@ -591,10 +594,13 @@ func (f *File) GetPictures(sheet, cell string) ([]Picture, error) {
|
||||||
}
|
}
|
||||||
col--
|
col--
|
||||||
row--
|
row--
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
if ws.Drawing == nil {
|
if ws.Drawing == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
6
sheet.go
6
sheet.go
|
@ -1843,8 +1843,6 @@ func (f *File) relsReader(path string) (*xlsxRelationships, error) {
|
||||||
// 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 (ws *xlsxWorksheet) prepareSheetXML(col int, row int) {
|
func (ws *xlsxWorksheet) prepareSheetXML(col int, row int) {
|
||||||
ws.mu.Lock()
|
|
||||||
defer ws.mu.Unlock()
|
|
||||||
rowCount := len(ws.SheetData.Row)
|
rowCount := len(ws.SheetData.Row)
|
||||||
sizeHint := 0
|
sizeHint := 0
|
||||||
var ht *float64
|
var ht *float64
|
||||||
|
@ -1878,9 +1876,7 @@ 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 (ws *xlsxWorksheet) makeContiguousColumns(fromRow, toRow, colCount int) {
|
||||||
ws.mu.Lock()
|
|
||||||
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)
|
||||||
|
|
31
styles.go
31
styles.go
|
@ -2004,10 +2004,13 @@ func (f *File) NewStyle(style *Style) (int, error) {
|
||||||
if fs.DecimalPlaces == 0 {
|
if fs.DecimalPlaces == 0 {
|
||||||
fs.DecimalPlaces = 2
|
fs.DecimalPlaces = 2
|
||||||
}
|
}
|
||||||
|
f.mu.Lock()
|
||||||
s, err := f.stylesReader()
|
s, err := f.stylesReader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return cellXfsID, err
|
return cellXfsID, err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
// check given style already exist.
|
// check given style already exist.
|
||||||
|
@ -2131,10 +2134,13 @@ func (f *File) getStyleID(ss *xlsxStyleSheet, style *Style) (int, error) {
|
||||||
// format by given style format. The parameters are the same with the NewStyle
|
// format by given style format. The parameters are the same with the NewStyle
|
||||||
// function.
|
// function.
|
||||||
func (f *File) NewConditionalStyle(style *Style) (int, error) {
|
func (f *File) NewConditionalStyle(style *Style) (int, error) {
|
||||||
|
f.mu.Lock()
|
||||||
s, err := f.stylesReader()
|
s, err := f.stylesReader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
fs, err := parseFormatStyleSet(style)
|
fs, err := parseFormatStyleSet(style)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -2179,7 +2185,9 @@ func (f *File) SetDefaultFont(fontName string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
font.Name.Val = stringPtr(fontName)
|
font.Name.Val = stringPtr(fontName)
|
||||||
|
f.mu.Lock()
|
||||||
s, _ := f.stylesReader()
|
s, _ := f.stylesReader()
|
||||||
|
f.mu.Unlock()
|
||||||
s.Fonts.Font[0] = font
|
s.Fonts.Font[0] = font
|
||||||
custom := true
|
custom := true
|
||||||
s.CellStyles.CellStyle[0].CustomBuiltIn = &custom
|
s.CellStyles.CellStyle[0].CustomBuiltIn = &custom
|
||||||
|
@ -2188,6 +2196,8 @@ func (f *File) SetDefaultFont(fontName string) error {
|
||||||
|
|
||||||
// readDefaultFont provides an un-marshalled font value.
|
// readDefaultFont provides an un-marshalled font value.
|
||||||
func (f *File) readDefaultFont() (*xlsxFont, error) {
|
func (f *File) readDefaultFont() (*xlsxFont, error) {
|
||||||
|
f.mu.Lock()
|
||||||
|
defer f.mu.Unlock()
|
||||||
s, err := f.stylesReader()
|
s, err := f.stylesReader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -2803,22 +2813,25 @@ func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error {
|
||||||
|
|
||||||
vColIdx := vCol - 1
|
vColIdx := vCol - 1
|
||||||
vRowIdx := vRow - 1
|
vRowIdx := vRow - 1
|
||||||
|
f.mu.Lock()
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.prepareSheetXML(vCol, vRow)
|
s, err := f.stylesReader()
|
||||||
makeContiguousColumns(ws, hRow, vRow, vCol)
|
if err != nil {
|
||||||
|
f.mu.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
f.mu.Unlock()
|
||||||
|
|
||||||
ws.mu.Lock()
|
ws.mu.Lock()
|
||||||
defer ws.mu.Unlock()
|
defer ws.mu.Unlock()
|
||||||
|
|
||||||
s, err := f.stylesReader()
|
ws.prepareSheetXML(vCol, vRow)
|
||||||
if err != nil {
|
ws.makeContiguousColumns(hRow, vRow, vCol)
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.mu.Lock()
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue