From 6aa59a1af29c21e0ece37fc94c66bc2999ed3540 Mon Sep 17 00:00:00 2001 From: Ri Xu Date: Mon, 24 Jul 2017 10:26:02 +0800 Subject: - Init insert/remove column/row support. Relate issue #77 and #82; - Readme and go test updated --- rows.go | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) (limited to 'rows.go') diff --git a/rows.go b/rows.go index 227a7d5..c45b49f 100644 --- a/rows.go +++ b/rows.go @@ -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: +// +// +// +// +// +// +// +// +// in this case, we should to change it to +// +// +// +// +// +// +// +// +// +// +// +// 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 +} -- cgit v1.2.1