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.64k stars 1.69k forks source link

Modify existing Excel file, leaves it "corrupted" (Excel does not get data from other cell) #1841

Closed RalfMetzingLeik closed 3 months ago

RalfMetzingLeik commented 3 months ago

Description

I've a program to modify an existing Excel file, which changes the number in on cell (source code and Excel file appended in Zip) Another sheet refers to this cell. After modifying the file with excelize (V2.8.1) and saving, then opening in Excel (Microsoft® Excel® für Microsoft 365 MSO (Version 2402 Build 16.0.17328.20124) 64 Bit ). Now the changed value ist changed in the cell, which is changed with excelize, but ist is not changed in the refering cell.

If I run the same with previous excelize (2.8.0), then i get a message on opening with excel, which says, that Excel found problems with the file and tries to fix. With V2.8.1. no message is shown. I think that the fixes in 2.8.1 do not fix all issues on the problem.

Another thing is, that the file size of the file saved by excelize ist about 10% less(!) than the original file on both versions (2.8.0 and 2.8.1)

Steps to reproduce the issue:

  1. Unzip the attached zip
  2. "go mod tidy"
  3. "go run ."
  4. open with Excel
  5. compare Filesizes "Input1.xlsx" vs "Output1.xlsx"
  6. Open "Output1.xlsx" with Excel
  7. Check Sheet "Rohdaten" Cell "E7" which has the new value (1 234 567.88)
  8. Check Sheet "Auswertung" Cell "D13" which refer to "=Rohdaten!E7" an shows the old value (2 797 332.10)
  9. Open "Input1.xlsx" with Excel
  10. Change value on "Rohdaten!E7" to any value
  11. Check "Auswertung!D13". -> It shows the new value

Describe the results you received: Cell "Auswertung!D13" is not updated/recalculated by Excel after opening "Output1.xlsx"

Describe the results you expected: Cell "Auswertung!D13" should show the value of "Rohdaten!E7" like in "Input1.xlsx"

Output of go version:

go version go1.22.0 windows/amd64

Excelize version or commit ID:

require github.com/xuri/excelize/v2 v2.8.1

require (
    github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
    github.com/richardlehane/mscfb v1.0.4 // indirect
    github.com/richardlehane/msoleps v1.0.3 // indirect
    github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect
    github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
    golang.org/x/crypto v0.19.0 // indirect
    golang.org/x/net v0.21.0 // indirect
    golang.org/x/text v0.14.0 // indirect
)

Environment details (OS, Microsoft Excel™ version, excelize-test.zip physical, etc.): Windows 11 Enterprise (V 22H2) running on virtual machine Microsoft® Excel® für Microsoft 365 MSO (Version 2402 Build 16.0.17328.20124) 64 Bit

xuri commented 3 months ago

Thanks for your issue. This is similar to the issues #634, #1195 and #1808. Please try to use UpdateLinkedValue to clean up the cell calculation cache value before saving the spreadsheet. In addition, you needn't create a new workbook if just save it as the new workbook, the code can be simply like this:

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)
-       }
-   }()
-
    // Test Change Data on existing complex excel-file
    f, err := excelize.OpenFile("Input1.xlsx")
    if err != nil {
        fmt.Println(err)
    }
    defer f.Close()

    sheet1 := f.GetSheetName(0)
    sheet2 := f.GetSheetName(1)
    f.SetCellStr(sheet1, "G1", "test_ralf")
    f.SetCellFloat(sheet2, "E7", 1234567.89, 2, 32)
+   if err = f.UpdateLinkedValue(); err != nil {
+       fmt.Println(err)
+       return
+   }
    f.SaveAs("Output1.xlsx")
}
RalfMetzingLeik commented 3 months ago

Thanks a lot, this solves the problem!

Just out of curiosity, what is the reason that the file is about 10% smaller after the "saveAs"?

xuri commented 3 months ago

The workbook file with the XLSX extension is a zipped, XML-based file format, and the size of the zipped folder (compression implementations by Go archive/zip package) by this library was different from the Office app.

RalfMetzingLeik commented 3 months ago

Thank you very much for the quick and detailed explanation.

xuri commented 3 months ago

You're welcome. Please close the issue if this problem has been resolved.