diff options
Diffstat (limited to 'rows.go')
-rw-r--r-- | rows.go | 135 |
1 files changed, 135 insertions, 0 deletions
@@ -1,7 +1,9 @@ package excelize import ( + "bytes" "encoding/xml" + "math" "strconv" "strings" ) @@ -209,3 +211,136 @@ func (f *File) GetRowVisible(sheet string, rowIndex int) bool { completeRow(xlsx, rows, cells) return !xlsx.SheetData.Row[rowIndex].Hidden } + +// RemoveRow provides function to remove single row by given worksheet index and +// row index. For example, remove row 3 in Sheet1: +// +// xlsx.RemoveRow("Sheet1", 2) +// +func (f *File) RemoveRow(sheet string, row int) { + if row < 0 { + return + } + xlsx := f.workSheetReader(sheet) + row++ + for i, r := range xlsx.SheetData.Row { + if r.R != row { + continue + } + xlsx.SheetData.Row = append(xlsx.SheetData.Row[:i], xlsx.SheetData.Row[i+1:]...) + f.adjustHelper(sheet, -1, row, -1) + return + } +} + +// InsertRow provides function to insert a new row before given row index. For +// example, create a new row before row 3 in Sheet1: +// +// xlsx.InsertRow("Sheet1", 2) +// +func (f *File) InsertRow(sheet string, row int) { + if row < 0 { + return + } + row++ + f.adjustHelper(sheet, -1, row, 1) +} + +// checkRow provides function to check and fill each column element for all rows +// and make that is continuous in a worksheet of XML. For example: +// +// <row r="15" spans="1:22" x14ac:dyDescent="0.2"> +// <c r="A15" s="2" /> +// <c r="B15" s="2" /> +// <c r="F15" s="1" /> +// <c r="G15" s="1" /> +// </row> +// +// in this case, we should to change it to +// +// <row r="15" spans="1:22" x14ac:dyDescent="0.2"> +// <c r="A15" s="2" /> +// <c r="B15" s="2" /> +// <c r="C15" s="2" /> +// <c r="D15" s="2" /> +// <c r="E15" s="2" /> +// <c r="F15" s="1" /> +// <c r="G15" s="1" /> +// </row> +// +// Noteice: this method could be very slow for large spreadsheets (more than +// 3000 rows one sheet). +func checkRow(xlsx *xlsxWorksheet) { + buffer := bytes.Buffer{} + for k, v := range xlsx.SheetData.Row { + lenCol := len(v.C) + if lenCol < 1 { + continue + } + endR := string(strings.Map(letterOnlyMapF, v.C[lenCol-1].R)) + endRow, _ := strconv.Atoi(strings.Map(intOnlyMapF, v.C[lenCol-1].R)) + endCol := TitleToNumber(endR) + 1 + if lenCol < endCol { + oldRow := xlsx.SheetData.Row[k].C + xlsx.SheetData.Row[k].C = xlsx.SheetData.Row[k].C[:0] + tmp := []xlsxC{} + for i := 0; i <= endCol; i++ { + buffer.WriteString(ToAlphaString(i)) + buffer.WriteString(strconv.Itoa(endRow)) + tmp = append(tmp, xlsxC{ + R: buffer.String(), + }) + buffer.Reset() + } + xlsx.SheetData.Row[k].C = tmp + for _, y := range oldRow { + colAxis := TitleToNumber(string(strings.Map(letterOnlyMapF, y.R))) + xlsx.SheetData.Row[k].C[colAxis] = y + } + } + } +} + +// completeRow provides function to check and fill each column element for a +// single row and make that is continuous in a worksheet of XML by given row +// index and axis. +func completeRow(xlsx *xlsxWorksheet, row, cell int) { + currentRows := len(xlsx.SheetData.Row) + if currentRows > 1 { + lastRow := xlsx.SheetData.Row[currentRows-1].R + if lastRow >= row { + row = lastRow + } + } + for i := currentRows; i < row; i++ { + xlsx.SheetData.Row = append(xlsx.SheetData.Row, xlsxRow{ + R: i + 1, + }) + } + buffer := bytes.Buffer{} + for ii := currentRows; ii < row; ii++ { + start := len(xlsx.SheetData.Row[ii].C) + if start == 0 { + for iii := start; iii < cell; iii++ { + buffer.WriteString(ToAlphaString(iii)) + buffer.WriteString(strconv.Itoa(ii + 1)) + xlsx.SheetData.Row[ii].C = append(xlsx.SheetData.Row[ii].C, xlsxC{ + R: buffer.String(), + }) + buffer.Reset() + } + } + } +} + +// convertRowHeightToPixels provides function to convert the height of a cell +// from user's units to pixels. If the height hasn't been set by the user we use +// the default value. If the row is hidden it has a value of zero. +func convertRowHeightToPixels(height float64) float64 { + var pixels float64 + if height == 0 { + return pixels + } + pixels = math.Ceil(4.0 / 3.0 * height) + return pixels +} |