diff options
-rw-r--r-- | adjust.go | 2 | ||||
-rw-r--r-- | adjust_test.go | 2 | ||||
-rw-r--r-- | calc.go | 2 | ||||
-rw-r--r-- | calc_test.go | 2 | ||||
-rw-r--r-- | calcchain.go | 2 | ||||
-rw-r--r-- | calcchain_test.go | 2 | ||||
-rw-r--r-- | cell.go | 2 | ||||
-rw-r--r-- | cell_test.go | 2 | ||||
-rw-r--r-- | chart.go | 2 | ||||
-rw-r--r-- | chart_test.go | 2 | ||||
-rw-r--r-- | col.go | 2 | ||||
-rw-r--r-- | col_test.go | 2 | ||||
-rw-r--r-- | comment.go | 2 | ||||
-rw-r--r-- | comment_test.go | 2 | ||||
-rw-r--r-- | crypt.go | 2 | ||||
-rw-r--r-- | crypt_test.go | 2 | ||||
-rw-r--r-- | datavalidation.go | 2 | ||||
-rw-r--r-- | datavalidation_test.go | 2 | ||||
-rw-r--r-- | date.go | 2 | ||||
-rw-r--r-- | date_test.go | 2 | ||||
-rw-r--r-- | docProps.go | 2 | ||||
-rw-r--r-- | docProps_test.go | 2 | ||||
-rw-r--r-- | drawing.go | 2 | ||||
-rw-r--r-- | drawing_test.go | 2 | ||||
-rw-r--r-- | errors.go | 2 | ||||
-rw-r--r-- | errors_test.go | 2 | ||||
-rw-r--r-- | excelize.go | 2 | ||||
-rw-r--r-- | excelize_test.go | 2 | ||||
-rw-r--r-- | file.go | 2 | ||||
-rw-r--r-- | file_test.go | 2 | ||||
-rw-r--r-- | formattedValue.go | 257 | ||||
-rw-r--r-- | go.mod | 4 | ||||
-rw-r--r-- | hsl.go | 2 | ||||
-rw-r--r-- | lib.go | 2 | ||||
-rw-r--r-- | lib_test.go | 2 | ||||
-rw-r--r-- | merge.go | 2 | ||||
-rw-r--r-- | merge_test.go | 2 | ||||
-rw-r--r-- | numfmt.go | 2 | ||||
-rw-r--r-- | numfmt_test.go | 2 | ||||
-rw-r--r-- | picture.go | 2 | ||||
-rw-r--r-- | picture_test.go | 2 | ||||
-rw-r--r-- | pivotTable.go | 2 | ||||
-rw-r--r-- | pivotTable_test.go | 2 | ||||
-rw-r--r-- | rows.go | 2 | ||||
-rw-r--r-- | rows_generic.go | 259 | ||||
-rw-r--r-- | rows_test.go | 2 | ||||
-rw-r--r-- | shape.go | 2 | ||||
-rw-r--r-- | shape_test.go | 2 | ||||
-rw-r--r-- | sheet.go | 2 | ||||
-rw-r--r-- | sheet_test.go | 2 | ||||
-rw-r--r-- | sheetpr.go | 2 | ||||
-rw-r--r-- | sheetpr_test.go | 2 | ||||
-rw-r--r-- | sheetview.go | 2 | ||||
-rw-r--r-- | sheetview_test.go | 2 | ||||
-rw-r--r-- | sparkline.go | 2 | ||||
-rw-r--r-- | sparkline_test.go | 2 | ||||
-rw-r--r-- | stream.go | 2 | ||||
-rw-r--r-- | stream_test.go | 2 | ||||
-rw-r--r-- | styles.go | 2 | ||||
-rw-r--r-- | styles_test.go | 2 | ||||
-rw-r--r-- | table.go | 2 | ||||
-rw-r--r-- | table_test.go | 2 | ||||
-rw-r--r-- | templates.go | 2 | ||||
-rw-r--r--[-rwxr-xr-x] | test/vbaProject.bin | bin | 16896 -> 16896 bytes | |||
-rw-r--r-- | vmlDrawing.go | 2 | ||||
-rw-r--r-- | workbook.go | 2 | ||||
-rw-r--r-- | workbook_test.go | 2 | ||||
-rw-r--r-- | xmlApp.go | 2 | ||||
-rw-r--r-- | xmlCalcChain.go | 2 | ||||
-rw-r--r-- | xmlChart.go | 2 | ||||
-rw-r--r-- | xmlChartSheet.go | 2 | ||||
-rw-r--r-- | xmlComments.go | 2 | ||||
-rw-r--r-- | xmlContentTypes.go | 2 | ||||
-rw-r--r-- | xmlCore.go | 2 | ||||
-rw-r--r-- | xmlDecodeDrawing.go | 2 | ||||
-rw-r--r-- | xmlDrawing.go | 2 | ||||
-rw-r--r-- | xmlPivotCache.go | 2 | ||||
-rw-r--r-- | xmlPivotTable.go | 2 | ||||
-rw-r--r-- | xmlSharedStrings.go | 2 | ||||
-rw-r--r-- | xmlStyles.go | 2 | ||||
-rw-r--r-- | xmlTable.go | 2 | ||||
-rw-r--r-- | xmlTheme.go | 2 | ||||
-rw-r--r-- | xmlWorkbook.go | 2 | ||||
-rw-r--r-- | xmlWorksheet.go | 2 |
84 files changed, 592 insertions, 88 deletions
@@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/adjust_test.go b/adjust_test.go index 3ce1796..d190ace 100644 --- a/adjust_test.go +++ b/adjust_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "fmt" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/calc_test.go b/calc_test.go index 1376c00..7079903 100644 --- a/calc_test.go +++ b/calc_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "container/list" diff --git a/calcchain.go b/calcchain.go index 5e511dc..a6d0c1f 100644 --- a/calcchain.go +++ b/calcchain.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/calcchain_test.go b/calcchain_test.go index 9eec804..d381cb6 100644 --- a/calcchain_test.go +++ b/calcchain_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "testing" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/cell_test.go b/cell_test.go index 40bab9b..a9c1624 100644 --- a/cell_test.go +++ b/cell_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "fmt" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/json" diff --git a/chart_test.go b/chart_test.go index 61e7c15..e18655e 100644 --- a/chart_test.go +++ b/chart_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "bytes" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/col_test.go b/col_test.go index 0ed1906..0f30da9 100644 --- a/col_test.go +++ b/col_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "path/filepath" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/comment_test.go b/comment_test.go index ead3939..2f9ece4 100644 --- a/comment_test.go +++ b/comment_test.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/xml" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/crypt_test.go b/crypt_test.go index a4a510e..38ea50a 100644 --- a/crypt_test.go +++ b/crypt_test.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "os" diff --git a/datavalidation.go b/datavalidation.go index 5ae5f65..0225073 100644 --- a/datavalidation.go +++ b/datavalidation.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "fmt" diff --git a/datavalidation_test.go b/datavalidation_test.go index c0d9117..dd3b36e 100644 --- a/datavalidation_test.go +++ b/datavalidation_test.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "math" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "math" diff --git a/date_test.go b/date_test.go index 4091e37..62dd81b 100644 --- a/date_test.go +++ b/date_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "fmt" diff --git a/docProps.go b/docProps.go index ebe929b..2496915 100644 --- a/docProps.go +++ b/docProps.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/docProps_test.go b/docProps_test.go index 64b690c..96551ad 100644 --- a/docProps_test.go +++ b/docProps_test.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "path/filepath" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/drawing_test.go b/drawing_test.go index 5c090eb..753e10b 100644 --- a/drawing_test.go +++ b/drawing_test.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/xml" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "errors" diff --git a/errors_test.go b/errors_test.go index 971802f..c5064fc 100644 --- a/errors_test.go +++ b/errors_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "testing" diff --git a/excelize.go b/excelize.go index f4c7a25..92617de 100644 --- a/excelize.go +++ b/excelize.go @@ -10,7 +10,7 @@ // data. This library needs Go version 1.15 or later. // // See https://xuri.me/excelize for more information about this package. -package excelize +package anyxcelize import ( "archive/zip" diff --git a/excelize_test.go b/excelize_test.go index ece74b2..15a8216 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "archive/zip" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "archive/zip" diff --git a/file_test.go b/file_test.go index 4272a7b..3dd4a62 100644 --- a/file_test.go +++ b/file_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "bufio" diff --git a/formattedValue.go b/formattedValue.go new file mode 100644 index 0000000..e59a8df --- /dev/null +++ b/formattedValue.go @@ -0,0 +1,257 @@ +package anyxcelize + +import ( + "strings" + "strconv" + "math" + "fmt" +) + +func (f *File) formattedValueGeneric(s int, v string, raw bool) (any, error) { + // fmt.Println("---") + + if raw { fmt.Println("fvg: raw"); return v, nil } + // s is the style reference + if s == 0 { fmt.Println("fvg: s==0"); return v, nil } + + styleSheet, err := f.stylesReader() + if err != nil { + fmt.Println("fvg: styleSheet err") + return v, err + } + if styleSheet.CellXfs == nil { + fmt.Println("fvg: CellXfs nil") + return v, err + } + + // TODO: what does this mean? + if s >= len(styleSheet.CellXfs.Xf) { + // fmt.Println("fvg: s >= len(...Xf)") + return v, err + } + + var numFmtID int + if styleSheet.CellXfs.Xf[s].NumFmtID != nil { + numFmtID = *styleSheet.CellXfs.Xf[s].NumFmtID + } + // Use this! + // fmt.Printf("xf[s].NumFmtID = %v\n", numFmtID) + + date1904 := false + wb, err := f.workbookReader() + if err != nil { + // fmt.Println("fvg: wb err") + return v, err + } + if wb != nil && wb.WorkbookPr != nil { + date1904 = wb.WorkbookPr.Date1904 + } + // NOTE: we get the formatting fn in ok, and + // call it with v, the numFmt, and date1904. + // We need to modify the functions that are + // possible to be ok, then, to return any. + // Only has up to ~60, so won't call on 167 (date), 164, 166 we have. + if ok := builtInNumFmtFuncGen[numFmtID]; ok != nil { + // fmt.Println("fvg: ok := ...") + // ok() is now a func(v, format string, date1904 bool) any !! + return ok(v, builtInNumFmt[numFmtID], date1904), err + } + + // This is what actually gets called, most of the time. + // This means NumFmts are NOT nil, so they exist, so + // does this mean we can do simple ParseFloat? + if styleSheet.NumFmts != nil { + // fmt.Printf("fvg: NumFmts != nil on (%s)\n", v) + // return v, err + } + + // If the above fails, we want this to work and return a correct + // value. + for _, xlsxFmt := range styleSheet.NumFmts.NumFmt { + if xlsxFmt.NumFmtID == numFmtID { + // fmt.Printf("Matched on numFmtID %v; date1904 %v format code %v\n", numFmtID, date1904, xlsxFmt.FormatCode) + return formatGeneric(v, xlsxFmt.FormatCode, date1904), err + } + } + + return v, err +} + +// builtInNumFmtFunc defined the format conversion functions map. Partial format +// code doesn't support currently and will return original string. +var builtInNumFmtFuncGen = map[int]func(v, format string, date1904 bool) any{ + 0: formatGeneric, + 1: formatToIntGeneric, // noted; yet to implement + 2: formatToFloatGeneric,// noted; yet to implement + 3: formatToIntSeparatorGeneric,// noted; yet to implement + 4: formatToFloatGeneric,// noted; yet to implement + 9: formatToCGeneric, + 10: formatToDGeneric, + 11: formatToEGeneric, + 12: formatGeneric, // Doesn't support currently + 13: formatGeneric, // Doesn't support currently + 14: formatGeneric, + 15: formatGeneric, + 16: formatGeneric, + 17: formatGeneric, + 18: formatGeneric, + 19: formatGeneric, + 20: formatGeneric, + 21: formatGeneric, + 22: formatGeneric, + 37: formatToAGeneric, + 38: formatToAGeneric, + 39: formatToBGeneric, + 40: formatToBGeneric, + 41: formatGeneric, // Doesn't support currently + 42: formatGeneric, // Doesn't support currently + 43: formatGeneric, // Doesn't support currently + 44: formatGeneric, // Doesn't support currently + 45: formatGeneric, + 46: formatGeneric, + 47: formatGeneric, + 48: formatToEGeneric, + 49: formatGeneric, +} + +// OnesGeneric to worry about implementing: +// formatToint, formatToFloat, formatToIntSeparator, formatTo{A,B,C,D,E} + +// Return any or int? +func formatToIntGeneric(v, format string, date1904 bool) any { + // Copied from original. Not sure what this does, probably don't want + // this to be the case. TODO: FIX + if strings.Contains(v, "_") { + magicerr := -420691111 + fmt.Printf("formatToIntGeneric: v %v, format %v, date1904 %v: error %v\n", v, format, date1904, magicerr) + return magicerr + } + + f, err := strconv.ParseFloat(v, 64) + if err != nil { + magicerr := -420691112 + fmt.Printf("formatToIntGeneric: v %v, format %v, date1904 %v: error %v\n", v, format, date1904, magicerr) + return magicerr + } // ERROR! + return math.Round(f) + // That should do us! +} + + +func formatToFloatGeneric(v, format string, date1904 bool) any { + if strings.Contains(v, "_") { return v } + f, err := strconv.ParseFloat(v, 64) + if err != nil { + magicerr := -420691113 + fmt.Printf("formatToFloatGeneric: v %v, format %v, date1904 %v: error %v\n", v, format, date1904, magicerr) + return magicerr + } + return f +} + +func formatToIntSeparatorGeneric(v, format string, date1904 bool) any { + if strings.Contains(v, "_") { + magicerr := -420691114 + fmt.Printf("formatToIntSeparatorGeneric: v %v, format %v, date1904 %v: error %v\n", v, format, date1904, magicerr) + return magicerr + } + f, err := strconv.ParseFloat(v, 64) + if err != nil { + magicerr := -420691115 + fmt.Printf("formatToIntSeparatorGeneric: v %v, format %v, date1904 %v: error %v\n", v, format, date1904, magicerr) + return magicerr + } + return math.Round(f) +} + +// Normally this would format as (100), 100 for -100, 100. This just returns +// an int here +func formatToAGeneric(v, format string, date1904 bool) any{ + return formatToIntGeneric(v, format, date1904) +} + +// The float equivalent of formatToA. Here just format as float! +func formatToBGeneric(v, format string, date1904 bool) any { + return formatToFloatGeneric(v, format, date1904) +} + +// Normally formats as percent. For now just keep it as is, AIEL pcts should +// be in 10.00 format anyways not 10%. If it is, eh. For now, just format as +// float, possibly better choices exist. +func formatToCGeneric(v, format string, date1904 bool) any { + return formatToFloatGeneric(v, format, date1904) +} + +// percents with 00.00% not 00%. Same as above, just do floats +func formatToDGeneric(v, format string, date1904 bool) any { + return formatToFloatGeneric(v, format, date1904) +} + +// based on %.2E, exponent? Yep, scientific notation. For this, I guess it is +// for floats, probably not integrals. Return as float. +func formatToEGeneric(v, format string, date1904 bool) any { + if strings.Contains(v, "_") { + fmt.Printf("formatToEGeneric: v %s, format %s, date1904 %s: error -420691116\n", v, format, date1904) + return -420691116 + } + f, err := strconv.ParseFloat(v, 64) + if err != nil { + fmt.Printf("formatToEGeneric: v %s, format %s, date1904 %s: error -420691116\n", v, format, date1904) + return -420691117 + } + return f +} + +func formatGeneric(v, format string, date1904 bool) any { + // Here we enumerate the possible format strings, and give either + // time.Time or int returns for them. + switch format { + case "\"TRUE\";\"TRUE\";\"FALSE\"": + if v == "0" { return false } else if v == "1" { return true } else { + // Error case. + fmt.Println("f in chat: %v cannot be parsed bool with %v", v, format) + } + case "General", "#,##0", "#,##0.00", "0", "0%", "0.00%", "0.00e+00": + return parseIOrF64(v) + case "d\\-mmm\\-yy", "[$-809]dd/mm/yy", "[$-809]mm/dd/yy", "mm/dd/yy", + "mm-dd-yy", "d-mmm-yy", "d-mmm", "mmm-yy", "h:mm am/pm", + "h:mm:ss am/pm", "hh:mm", "hh:mm:ss", "m/d/y hh:mm": + // If it's an integer, it's a complete date. We don't really + // need to care about preserving time, which is the fractional + // component: yet! TODO: care about the fractional component, + // but for now let's just parse as is. + // We just need to convert Excel integer time to our format. + xlTime, err := strconv.ParseFloat(v, 64) + if err != nil { + fmt.Printf("formatGeneric: f in chat for %v, which can't be parsed into float in %v case statement; %v error", v, format, err) + panic("panic! formatGeneric") // TODO: handle this error better. + } + f := timeFromExcelTime(xlTime, date1904) + return f + default: + // Default: just parse integer or float! Though this is not a + // perfect solution. + fmt.Println("Ok, running default case") + return parseIOrF64(v) + } + return -420699999 +} + +/* pure */ func parseIOrF64(v string) any { + gv, err := strconv.ParseInt(v, 10, 64) + if err != nil { + fv, err := strconv.ParseFloat(v, 64) + if err != nil { + // What do? + fmt.Printf("formatGeneric: general format cannot parse as int or float [%v]\n", v) + return "parseIOrF64 fail" + } + return fv + } + return gv +} + +// NOTE +// This is re-writing these as these are functions that read into strings for +// reading. I am not sure if they are used for writing, but if so eh. Probably +// not as writing can manage with the actual types. @@ -1,6 +1,6 @@ -module git.gabbott.dev/george/excelize/v2 +module anyxcelize -go 1.16 +go 1.19 require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 @@ -26,7 +26,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -package excelize +package anyxcelize import ( "image/color" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "archive/zip" diff --git a/lib_test.go b/lib_test.go index ec5fd64..942f175 100644 --- a/lib_test.go +++ b/lib_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "archive/zip" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "strings" diff --git a/merge_test.go b/merge_test.go index 31f2cf4..e75dc75 100644 --- a/merge_test.go +++ b/merge_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "path/filepath" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "fmt" diff --git a/numfmt_test.go b/numfmt_test.go index f45307d..fb76fd8 100644 --- a/numfmt_test.go +++ b/numfmt_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "testing" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/picture_test.go b/picture_test.go index 11196c6..815fa55 100644 --- a/picture_test.go +++ b/picture_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "fmt" diff --git a/pivotTable.go b/pivotTable.go index 7b4b553..6624074 100644 --- a/pivotTable.go +++ b/pivotTable.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/xml" diff --git a/pivotTable_test.go b/pivotTable_test.go index fc9e090..892ee16 100644 --- a/pivotTable_test.go +++ b/pivotTable_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "fmt" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/rows_generic.go b/rows_generic.go index fff3019..87f4087 100644 --- a/rows_generic.go +++ b/rows_generic.go @@ -1,10 +1,10 @@ -package excelize +package anyxcelize import ( - // "bytes" + "bytes" "encoding/xml" "errors" - // "fmt" + "fmt" // "io" // "math" "strings" @@ -14,6 +14,226 @@ import ( // "github.com/mohae/deepcopy" ) +// Functions: cols + +// Rows return the current column's row values. +func (cols *ColsGeneric) RowsGeneric(opts ...Options) ([]any, error) { + var rowIterator rowXMLIteratorGeneric + if cols.stashCol >= cols.curCol { + return rowIterator.cells, rowIterator.err + } + cols.rawCellValue = parseOptions(opts...).RawCellValue + if cols.sst, rowIterator.err = cols.f.sharedStringsReader(); rowIterator.err != nil { + return rowIterator.cells, rowIterator.err + } + decoder := cols.f.xmlNewDecoder(bytes.NewReader(cols.sheetXML)) + for { + token, _ := decoder.Token() + if token == nil { + break + } + switch xmlElement := token.(type) { + case xml.StartElement: + rowIterator.inElement = xmlElement.Name.Local + if rowIterator.inElement == "row" { + rowIterator.cellCol = 0 + rowIterator.cellRow++ + attrR, _ := attrValToInt("r", xmlElement.Attr) + if attrR != 0 { + rowIterator.cellRow = attrR + } + } + if cols.rowXMLHandlerGeneric(&rowIterator, &xmlElement, decoder); rowIterator.err != nil { + return rowIterator.cells, rowIterator.err + } + case xml.EndElement: + if xmlElement.Name.Local == "sheetData" { + return rowIterator.cells, rowIterator.err + } + } + } + return rowIterator.cells, rowIterator.err +} + +func (f *File) ColsGeneric(sheet string) (*ColsGeneric, error) { + name, ok := f.getSheetXMLPath(sheet) + if !ok { + return nil, ErrSheetNotExist{sheet} + } + if ws, ok := f.Sheet.Load(name); ok && ws != nil { + worksheet := ws.(*xlsxWorksheet) + worksheet.Lock() + defer worksheet.Unlock() + output, _ := xml.Marshal(worksheet) + f.saveFileList(name, f.replaceNameSpaceBytes(name, output)) + } + var colIterator columnXMLIteratorGeneric // do me ! + colIterator.cols.sheetXML = f.readBytes(name) + decoder := f.xmlNewDecoder(bytes.NewReader(colIterator.cols.sheetXML)) + for { + token, _ := decoder.Token() + if token == nil { + break + } + switch xmlElement := token.(type) { + case xml.StartElement: + columnXMLHandlerGeneric(&colIterator, &xmlElement) + if colIterator.err != nil { + return &colIterator.cols, colIterator.err + } + case xml.EndElement: + if xmlElement.Name.Local == "sheetData" { + colIterator.cols.f = f + colIterator.cols.sheet = trimSheetName(sheet) + return &colIterator.cols, nil + } + } + } + return &colIterator.cols, nil +} + +// columnXMLHandler parse the column XML element of the worksheet. +func columnXMLHandlerGeneric(colIterator *columnXMLIteratorGeneric, xmlElement *xml.StartElement) { + colIterator.err = nil + inElement := xmlElement.Name.Local + if inElement == "row" { + colIterator.row++ + for _, attr := range xmlElement.Attr { + if attr.Name.Local == "r" { + if colIterator.curRow, colIterator.err = strconv.Atoi(attr.Value); colIterator.err != nil { + return + } + colIterator.row = colIterator.curRow + } + } + colIterator.cols.totalRows = colIterator.row + colIterator.cellCol = 0 + } + if inElement == "c" { + colIterator.cellCol++ + for _, attr := range xmlElement.Attr { + if attr.Name.Local == "r" { + if colIterator.cellCol, _, colIterator.err = CellNameToCoordinates(attr.Value); colIterator.err != nil { + return + } + } + } + if colIterator.cellCol > colIterator.cols.totalCols { + colIterator.cols.totalCols = colIterator.cellCol + } + } +} + + +// columnXMLIterator defined runtime use field for the worksheet column SAX parser. +type columnXMLIteratorGeneric struct { + err error + cols ColsGeneric + cellCol, curRow, row int +} + +type ColsGeneric struct { + err error + curCol, totalCols, totalRows, stashCol int + rawCellValue bool + sheet string + f *File + sheetXML []byte + sst *xlsxSST +} + +// rowXMLHandler parse the row XML element of the worksheet. +func (cols *ColsGeneric) rowXMLHandlerGeneric(rowIterator *rowXMLIteratorGeneric, xmlElement *xml.StartElement, decoder *xml.Decoder) { + if rowIterator.inElement == "c" { + rowIterator.cellCol++ + for _, attr := range xmlElement.Attr { + if attr.Name.Local == "r" { + if rowIterator.cellCol, rowIterator.cellRow, rowIterator.err = CellNameToCoordinates(attr.Value); rowIterator.err != nil { + return + } + } + } + blank := rowIterator.cellRow - len(rowIterator.cells) + for i := 1; i < blank; i++ { + rowIterator.cells = append(rowIterator.cells, "") + } + if rowIterator.cellCol == cols.curCol { + colCell := xlsxC{} + _ = decoder.DecodeElement(&colCell, xmlElement) + val, _ := colCell.getValueFrom(cols.f, cols.sst, cols.rawCellValue) + rowIterator.cells = append(rowIterator.cells, val) + } + } +} +func (f *File) GetColsGeneric(sheet string, opts ...Options) ([][]any, error) { + cols, err := f.ColsGeneric(sheet) + if err != nil { + return nil, err + } + results := make([][]any, 0, 64) + for cols.Next() { + col, _ := cols.RowsGeneric(opts...) + results = append(results, col) + } + return results, nil +} + + +// Next will return true if the next column is found. +func (cols *ColsGeneric) Next() bool { + cols.curCol++ + return cols.curCol <= cols.totalCols +} + +// Error will return an error when the error occurs. +func (cols *ColsGeneric) Error() error { + return cols.err +} + +// Rows return the current column's row values. +func (cols *ColsGeneric) Rows(opts ...Options) ([]any, error) { + var rowIterator rowXMLIteratorGeneric + if cols.stashCol >= cols.curCol { + return rowIterator.cells, rowIterator.err + } + cols.rawCellValue = parseOptions(opts...).RawCellValue + if cols.sst, rowIterator.err = cols.f.sharedStringsReader(); rowIterator.err != nil { + return rowIterator.cells, rowIterator.err + } + decoder := cols.f.xmlNewDecoder(bytes.NewReader(cols.sheetXML)) + for { + token, _ := decoder.Token() + if token == nil { + break + } + switch xmlElement := token.(type) { + case xml.StartElement: + rowIterator.inElement = xmlElement.Name.Local + if rowIterator.inElement == "row" { + rowIterator.cellCol = 0 + rowIterator.cellRow++ + attrR, _ := attrValToInt("r", xmlElement.Attr) + if attrR != 0 { + rowIterator.cellRow = attrR + } + } + if cols.rowXMLHandlerGeneric(&rowIterator, &xmlElement, decoder); rowIterator.err != nil { + return rowIterator.cells, rowIterator.err + } + case xml.EndElement: + if xmlElement.Name.Local == "sheetData" { + return rowIterator.cells, rowIterator.err + } + } + } + return rowIterator.cells, rowIterator.err +} + + + + +// Functions: rows + func (f *File) GetRowsGeneric(sheet string, opts ...Options) ([][]any, error) { rows, err := f.RowsGeneric(sheet) if err != nil { @@ -194,8 +414,10 @@ func (c *xlsxC) getValueFromGeneric(f *File, d *xlsxSST, raw bool) (any, error) defer f.Unlock() switch c.T { case "b": // done, not tested + // fmt.Println("Calling c.getcellBoolGeneric") return c.getCellBoolGeneric(f, raw) case "d": // done, not tested + // fmt.Println("Calling c.getCellDateGeneric") return c.getCellDateGeneric(f, raw) case "s": // Don't touch, strings are a-ok if c.V != "" { @@ -216,6 +438,7 @@ func (c *xlsxC) getValueFromGeneric(f *File, d *xlsxSST, raw bool) (any, error) return f.formattedValue(c.S, c.V, raw) default: // For integrals and floatings? These need to go into int or float64. // We need to change it to return an int or a decimal. + // fmt.Println("Calling c.getCellNumeric") return c.getCellNumeric(f, raw) // if isNum, precision, decimal := isNumeric(c.V); isNum && !raw { // if precision > 15 { @@ -239,7 +462,7 @@ func (c *xlsxC) getCellBoolGeneric(f *File, raw bool) (any, error) { return false, nil } - return f.formattedValue(c.S, c.V, raw) + return f.formattedValueGeneric(c.S, c.V, raw) } // TODO: I probably actually have to like, do something, to get a valid @@ -253,6 +476,7 @@ func (c *xlsxC) getCellBoolGeneric(f *File, raw bool) (any, error) { // function not to call formattedValue, and just to return a proper date like // it should. I don't want to return a float64, but a time.Time I believe. func (c *xlsxC) getCellDateGeneric(f *File, raw bool) (time.Time, error) { + fmt.Printf("getCellDateGeneric with date %v\n", c.V) // if !raw { layout := "20060102T150405.999" if strings.HasSuffix(c.V, "Z") { @@ -284,18 +508,41 @@ func (c *xlsxC) getCellDateGeneric(f *File, raw bool) (time.Time, error) { // For now, we could just try parse as a float, and if it doesn't work parse as // an int, and if it doesn't work cry. func (c *xlsxC) getCellNumeric(f *File, raw bool) (any, error) { + // fmt.Printf("rows.getCellNumeric with value %v\n", c.V) // This can either be a float or an int. If it is a float, return a // float64. Otherwise, return an int. /* TODO: implement according to above comment. */ if isNum, precision, decimal := isNumeric(c.V); isNum && !raw { + // fmt.Printf("isNum true, prec{%v} ; decimal(%v)\n", precision, decimal) + + /* new way, see comment below */ + /* 2023-02-28: I'm commenting this out to try have it call + * formattedValueGeneric, which should (?) solve my worries. */ + // v, err := strconv.ParseInt(c.V, 10, 64) + // if err != nil { + // return strconv.ParseFloat(c.V, 64) + // } + // return v, err + + + if precision > 15 { + // We actually just need a way to return a float. I + // say try return int first, if it doesn't work try + // float, else cry and die. // Return here a float64 + // r, err := strconv.ParseFloat(c.V, 64) + // fmt.Printf("prec15: ret(%v)\n", r) + // return r, err c.V = strconv.FormatFloat(decimal, 'G', 15, 64) } else { // I think, return here an int? + // return strconv.ParseInt(c.V, 10, 64) c.V = strconv.FormatFloat(decimal, 'f', -1, 64) } - } - return f.formattedValue(c.S, c.V, raw) + } + // fmt.Printf("getCellNumeric is failing, value %v\n", c.V) + // return nil, errors.New("getCellNumeric failed like") + return f.formattedValueGeneric(c.S, c.V, raw) } diff --git a/rows_test.go b/rows_test.go index 2e49c28..7692bbe 100644 --- a/rows_test.go +++ b/rows_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "bytes" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/json" diff --git a/shape_test.go b/shape_test.go index 2b2e87c..537e41a 100644 --- a/shape_test.go +++ b/shape_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "path/filepath" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/sheet_test.go b/sheet_test.go index 2494cfb..341be0b 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "encoding/xml" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "reflect" diff --git a/sheetpr_test.go b/sheetpr_test.go index d422e3f..cadb352 100644 --- a/sheetpr_test.go +++ b/sheetpr_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "testing" diff --git a/sheetview.go b/sheetview.go index 9845942..758d01a 100644 --- a/sheetview.go +++ b/sheetview.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize // getSheetView returns the SheetView object func (f *File) getSheetView(sheet string, viewIndex int) (*xlsxSheetView, error) { diff --git a/sheetview_test.go b/sheetview_test.go index 8d022a2..aaba28f 100644 --- a/sheetview_test.go +++ b/sheetview_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "testing" diff --git a/sparkline.go b/sparkline.go index 0c32462..70a3fb0 100644 --- a/sparkline.go +++ b/sparkline.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/xml" diff --git a/sparkline_test.go b/sparkline_test.go index e20dfdc..4213be5 100644 --- a/sparkline_test.go +++ b/sparkline_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "fmt" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/stream_test.go b/stream_test.go index bdf634e..fc5d5dc 100644 --- a/stream_test.go +++ b/stream_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "encoding/xml" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/styles_test.go b/styles_test.go index 9001d5b..be51862 100644 --- a/styles_test.go +++ b/styles_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "fmt" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/json" diff --git a/table_test.go b/table_test.go index 5ac464b..b2b822c 100644 --- a/table_test.go +++ b/table_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "fmt" diff --git a/templates.go b/templates.go index 2e0c051..f85aa65 100644 --- a/templates.go +++ b/templates.go @@ -12,7 +12,7 @@ // This file contains default templates for XML files we don't yet populated // based on content. -package excelize +package anyxcelize const ( defaultXMLPathContentTypes = "[Content_Types].xml" diff --git a/test/vbaProject.bin b/test/vbaProject.bin Binary files differindex fc15dca..fc15dca 100755..100644 --- a/test/vbaProject.bin +++ b/test/vbaProject.bin diff --git a/vmlDrawing.go b/vmlDrawing.go index f9de499..e34a3c8 100644 --- a/vmlDrawing.go +++ b/vmlDrawing.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/workbook.go b/workbook.go index eb57cb5..a4106b8 100644 --- a/workbook.go +++ b/workbook.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "bytes" diff --git a/workbook_test.go b/workbook_test.go index a3b2b52..4eb1cc8 100644 --- a/workbook_test.go +++ b/workbook_test.go @@ -1,4 +1,4 @@ -package excelize +package anyxcelize import ( "testing" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlCalcChain.go b/xmlCalcChain.go index 9e25d50..b683b42 100644 --- a/xmlCalcChain.go +++ b/xmlCalcChain.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlChart.go b/xmlChart.go index 5165ea0..9209391 100644 --- a/xmlChart.go +++ b/xmlChart.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlChartSheet.go b/xmlChartSheet.go index f0f2f62..8af1e0c 100644 --- a/xmlChartSheet.go +++ b/xmlChartSheet.go @@ -11,7 +11,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlComments.go b/xmlComments.go index 7b67e67..0d02ad7 100644 --- a/xmlComments.go +++ b/xmlComments.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlContentTypes.go b/xmlContentTypes.go index 52dd744..a5bd190 100644 --- a/xmlContentTypes.go +++ b/xmlContentTypes.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/xml" @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlDecodeDrawing.go b/xmlDecodeDrawing.go index fb920be..2ff3fb7 100644 --- a/xmlDecodeDrawing.go +++ b/xmlDecodeDrawing.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlDrawing.go b/xmlDrawing.go index 56ddc0e..e30ed45 100644 --- a/xmlDrawing.go +++ b/xmlDrawing.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/xml" diff --git a/xmlPivotCache.go b/xmlPivotCache.go index 0af7c44..bb372bb 100644 --- a/xmlPivotCache.go +++ b/xmlPivotCache.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlPivotTable.go b/xmlPivotTable.go index 897669b..0c5aca4 100644 --- a/xmlPivotTable.go +++ b/xmlPivotTable.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlSharedStrings.go b/xmlSharedStrings.go index 7dac544..5aa4b2f 100644 --- a/xmlSharedStrings.go +++ b/xmlSharedStrings.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlStyles.go b/xmlStyles.go index c9e0761..b36a6c0 100644 --- a/xmlStyles.go +++ b/xmlStyles.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/xml" diff --git a/xmlTable.go b/xmlTable.go index 758e0ea..2d1dcc1 100644 --- a/xmlTable.go +++ b/xmlTable.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlTheme.go b/xmlTheme.go index 80bb3af..89c3568 100644 --- a/xmlTheme.go +++ b/xmlTheme.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import "encoding/xml" diff --git a/xmlWorkbook.go b/xmlWorkbook.go index e384807..e546b85 100644 --- a/xmlWorkbook.go +++ b/xmlWorkbook.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/xml" diff --git a/xmlWorksheet.go b/xmlWorksheet.go index 263c2a3..8f37f2f 100644 --- a/xmlWorksheet.go +++ b/xmlWorksheet.go @@ -9,7 +9,7 @@ // API for generating or reading data from a worksheet with huge amounts of // data. This library needs Go version 1.15 or later. -package excelize +package anyxcelize import ( "encoding/xml" |