qax-os / excelize

Go language library for reading and writing Microsoft Excel™ (XLAM / XLSM / XLSX / XLTM / XLTX) spreadsheets
https://xuri.me/excelize
BSD 3-Clause "New" or "Revised" License
17.62k stars 1.68k forks source link

RemoveRow() return a strange error in the latest version(2.8.1) #1896

Open mqjyl opened 1 month ago

mqjyl commented 1 month ago

Description

Steps to reproduce the issue:

When I use the latest version(v2.8.1) to delete some rows in the file, I always get the following error:

invalid column name "K14 K"

Code:

rows, err := f.GetRows(sheet)
if err != nil {
    return err
}
for i := len(rows); i >= 5; i-- {
    if err = f.RemoveRow(sheet, i); err != nil {
    fmt.Sprintf("f.remove row failed: %v", err)
    return err
    }
}

There was no such problem using the previous version, such as v2.6.1。The test file has been posted in the link。 template.xlsx

Output of go version:

go 1.21

Excelize version or commit ID:

v2.8.1

Environment details (OS, Microsoft Excel™ version, physical, etc.):

MacOS
rednexela1941 commented 1 month ago

ran into a similar thing using InsertRows:

invalid column name "K31 E"
rednexela1941 commented 1 month ago

Some investigations:

Seems that the sheet I was reading and editing was using the same data validation twice.

inside of adjust.go

func (f *File) adjustDataValidations(ws *xlsxWorksheet, sheet string, dir adjustDirection, num, offset, sheetID int) error {
    for _, sheetN := range f.GetSheetList() {
        worksheet, err := f.workSheetReader(sheetN)
        if err != nil {
            if err.Error() == newNotWorksheetError(sheetN).Error() {
                continue
            }
            return err
        }
        if worksheet.DataValidations == nil {
            return nil
        }
        for i := 0; i < len(worksheet.DataValidations.DataValidation); i++ {
            dv := worksheet.DataValidations.DataValidation[i]
            if dv == nil {
                continue
            }
            if sheet == sheetN {
                fmt.Println("dv.Sqref", dv.Sqref) /// <<----------------HERE
                ref, del, err := f.adjustCellRef(dv.Sqref, dir, num, offset)

it was feeding two ranges:

dv.Sqref K9:K31 E8:E30

which in turn blew up the insides of lib.go:rangeRefToCoordinates

func rangeRefToCoordinates(ref string) ([]int, error) {
    rng := strings.Split(strings.ReplaceAll(ref, "$", ""), ":")
    if len(rng) < 2 {
        return nil, ErrParameterInvalid
    }
    fmt.Println(ref, "ref", rng[0], rng[1]) // HERE
    return cellRefsToCoordinates(rng[0], rng[1])
}

output:

K9:K31 E8:E30 ref K9 K31 E8

Temporary fix for me was to remove the problematic datavalidations before editing the sheet:

    if err := f.DeleteDataValidation(sheetName, "K9:K31", "E8:E30"); err != nil {
        return err
    }