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

sw.SetRow() Can only be called once #1882

Closed mohuaiyuan closed 2 months ago

mohuaiyuan commented 2 months ago

Description

    styleID, err = f.NewStyle(&excelize.Style{Font: &excelize.Font{Color: "CFCFCF"}})
err = sw.SetRow("A1", []interface{}{excelize.Cell{Value: "产品信息", StyleID: styleID}})
err = sw.MergeCell("A1", "B1")
err = sw.SetRow("C1", []interface{}{excelize.Cell{Value: "产品分类", StyleID: styleID}})
err = sw.MergeCell("C1", "D1")

   我需要导出一个拥有多行标题的表格,第一行标题需要合并单元格并设置值
   之前2.6.1使用以上代码可以实现,在2.8.1版本下则会报错:row 1 has already been written
   最终导致第一行标题行,只有第一个合并的单元格设置值成功,第二个合并的单元格设置值失败。

Steps to reproduce the issue: 1.流式导出大数据量,实现多级表头 2.一级表头标题行需要合并单元格并设置标题 3.使用sw.SetRow和sw.MergeCell在2.8.1版本无法实现

Describe the results you received:

Describe the results you expected:

Output of go version:

(paste your output here)

Excelize version or commit ID:

(paste here)

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

mohuaiyuan commented 2 months ago

styleID, err := f.NewStyle(&excelize.Style{Font: &excelize.Font{Color: "CFCFCF"}}) err = sw.MergeCell("A1", "B1") err = sw.MergeCell("C1", "D1") 尝试过先合并单元格 然后使用以下两种写法均不能实现 sw.SetRow("A1", []interface{}{excelize.Cell{Value: "产品信息", StyleID: styleID}, excelize.Cell{Value: "产品分类", StyleID: styleID}}) sw.SetRow("A1", []interface{}{"产品信息", "产品分类"}) 最终都只会出现第一个合并的单元格有值,后面的单元格空白无值。

mohuaiyuan commented 2 months ago

最后 经过对比2.6.1和2.8.1版本源码和阅读发布日志, 应该是在2.7.0版本中优化SetRow方法导致出现上面问题,但是没有找到解决方法, 个人尝试解决,只需要将SetRow方法中 if row <= sw.rows { return newStreamSetRowError(row) } 修改为 if row < sw.rows { return newStreamSetRowError(row) } 即可解决上面的问题。

xuri commented 2 months ago

Thanks for your issue. Please using the nil value to represent the blank cell in set sheet rows, for example:

package main

import (
    "fmt"

    "github.com/xuri/excelize/v2"
)

func main() {
    f := excelize.NewFile()
    defer func() {
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()
    styleID, err := f.NewStyle(&excelize.Style{
        Font: &excelize.Font{Color: "CFCFCF"},
    })
    if err != nil {
        fmt.Println(err)
        return
    }
    sw, err := f.NewStreamWriter("Sheet1")
    if err != nil {
        fmt.Println(err)
        return
    }
    if err = sw.SetRow("A1", []interface{}{
        excelize.Cell{Value: "产品信息", StyleID: styleID}, // A1
        nil, // B1
        excelize.Cell{Value: "产品分类", StyleID: styleID}, // C1
    }); err != nil {
        fmt.Println(err)
        return
    }
    if err = sw.MergeCell("A1", "B1"); err != nil {
        fmt.Println(err)
        return
    }
    if err = sw.MergeCell("C1", "D1"); err != nil {
        fmt.Println(err)
        return
    }
    if err = sw.Flush(); err != nil {
        fmt.Println(err)
        return
    }
    if err = f.SaveAs("Book1.xlsx"); err != nil {
        fmt.Println(err)
    }
}

I'll close this issue. If you have any questions, please let me know, and you can reopen this anytime.