excelize
excelize copied to clipboard
Table data extraction
- Added method GetTableData to extract raw table values
- Added method GetTableColumns to extract values with their columns
I'm not so sure about the naming of these functions, feel free to rename them however you want
PR Details
I needed to extract values from a table, and I found out it is hard for the user to use the GetTables
to actually access the data (need to convert the range to coordinates and manually walk the cells).
So I added a couple of methods to access the table's values with structured ways.
Description
Related Issue
Motivation and Context
How Has This Been Tested
I added the unit test for the methods I created. I ran all the tests locally.
Types of changes
- [ ] Docs change / refactoring / dependency upgrade
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
Checklist
- [ ] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have read the CONTRIBUTING document.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
Anything else needed to merge this in? @xuri
Sorry for my late reply. Thanks for your pull request. Unfortunately, due to the principle of minimum availability, I didn't suggest introducing these functions to keep the library core and easy. Anyone can easily make a custom function to get cells in the table range by themselves: table cell value, table cell formula, table cell style, table cell conditional formatting rules, etc., The developers can implement that by the wrapper or composite the existing exported functions.
It cannot be implemented by the developer since there is no way to access the coordinates of the table by its range (in-order to iterate over the table's cells). I agree that it extends functionality of the library, but as of now I don't see a way of doing it with the current API (unless I copy code from the library to my code, which defeats the purpose)
Excelize library provides a set of utility functions to convert between cell reference and column/row number, so the user can get table range, convert the range to coordinates, and walk the cells by simple code just like in this pull request. Users can get table cell value, table cell formula, table cell style, table cell conditional formatting rules, formula, etc. when walking the cells, so I do not suggest adding a series function for each scenario of the above: GetTableData
, GetTableCellStyle
, GetTableCellConditionalFormatting
, GetTableCellFormula
, etc., Here is a standalone example for get cell value in table range base on this pull request:
package main
import (
"fmt"
"math/rand"
"strings"
"github.com/xuri/excelize/v2"
)
func main() {
f := excelize.NewFile()
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
// Generate random numbers and set cell values in the table range
for rowNum := 2; rowNum <= 5; rowNum++ {
row := make([]interface{}, 5)
for colID := 0; colID < 5; colID++ {
row[colID] = rand.Intn(100)
}
cell, err := excelize.CoordinatesToCellName(1, rowNum)
if err != nil {
fmt.Println(err)
return
}
if err := f.SetSheetRow("Sheet1", cell, &row); err != nil {
fmt.Println(err)
return
}
}
// Add a table
if err := f.AddTable("Sheet1", &excelize.Table{
Range: "A1:E5",
Name: "table",
StyleName: "TableStyleMedium2",
ShowFirstColumn: true,
ShowLastColumn: true,
ShowColumnStripes: true,
}); err != nil {
fmt.Println(err)
return
}
tables, err := f.GetTables("Sheet1")
if err != nil {
fmt.Println(err)
return
}
for _, table := range tables {
// Get table range, convert the range to coordinates
tableRange := strings.Split(table.Range, ":")
if len(tableRange) != 2 {
return
}
fromCol, fromRow, err := excelize.CellNameToCoordinates(tableRange[0])
if err != nil {
fmt.Println(err)
return
}
toCol, toRow, err := excelize.CellNameToCoordinates(tableRange[1])
if err != nil {
fmt.Println(err)
return
}
// Walk the cells of the table
for rowNum := fromRow; rowNum <= toRow; rowNum++ {
for colNum := fromCol; colNum <= toCol; colNum++ {
cell, err := excelize.CoordinatesToCellName(colNum, rowNum)
if err != nil {
fmt.Println(err)
return
}
val, err := f.GetCellValue("Sheet1", cell)
if err != nil {
fmt.Println(err)
return
}
fmt.Print(val, "\t")
}
fmt.Println()
}
}
if err := f.SaveAs("Book1.xlsx"); err != nil {
fmt.Println(err)
}
}