请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册

QQ登录

只需一步,快速开始

低调的繁华
金牌服务用户   /  发表于:2025-3-19 18:57  /   查看:185  /  回复:9
1金币
本帖最后由 Matthew.Xue 于 2025-3-20 12:17 编辑


调研编号:DOCXLS-12100

当前gc【7.0.3】基于sjs格式文件读取单元格的value时,与之前版本【6.1.1】的ssjson不一致,如下所示
设计器中公式如下:
image.png923441772.png
在后端gc【7.0.3】基于此模板ssjson格式读取时,不关闭自动计算getValue()读取到的值为1,在关闭后端自动计算读取到的值为3
在后端gc【7.0.3】基于此模板sjs格式读取时,不关闭自动计算getValue()读取到的值为3,在关闭后端自动计算读取到的值为3。


同一个版本不同的文件格式读取的值是不一样的,但是我们在导出excel时A2单元格的值为1,相关案例如下:
image.png696153869.png


问题如下:
gc是不是在新版本的sjs做了升级,兼容了部分公式计算文本的处理?
gc和spreadjs是不是要跟我们的excel保持一致呢?因为按照目前的处理我们在将相关的报表文件导出excel时就会出现类似的线上线下值不一致问题。

GcExcelDemo 3.zip

53.62 KB, 下载次数: 3

9 个回复

倒序浏览
Matthew.Xue
超级版主   /  发表于:2025-3-20 09:53:03
沙发
本帖最后由 Matthew.Xue 于 2025-3-20 09:59 编辑

您好,这里涉及到多个问题,我给您逐个解答:

1. SpreadJS、GcExcel、Excel在部分公式计算时本身就有区别。
以您的demo为例,当计算sum(1, "2")的时候,SpreadJS的结果是3,而GcExcel和Excel不会让字符串2参与计算,所以计算的结果都是1。

2. 为了解决1中的问题,SpreadJS支持Excel兼容的计算模式,打开后重新计算,SpreadJS的计算结果也会是1
  1. GC.Spread.CalcEngine.ExcelCompatibleCalcMode = true
  2. spread.calculate()
复制代码

GIF 2025-3-20 9-50-53.gif
3. SpreadJS和GcExcel在关闭计算的情况下,对于公式单元格会读取之前计算好的缓存的值(即3),Excel也是一样,由于我这里的xlsx文件是从网络下载的,Excel不会自动启用编辑,所以我打开您的Excel文件时,A2单元格的计算结果也是3,只有当我点击了“编辑”后,它的结果才会变成1
GIF 2025-3-20 9-44-51.gif

4. gcexcel在开启计算(默认)的情况下,读取ssjson后会自动进行计算,但打开sjs文件时不会自动计算,所以才会出现您说的打开sjs文件时,不论是否关闭计算,A2单元格的结果都是3(读取了sjs文件中缓存的计算结果),而ssjson则只有在关闭计算的情况下才是3,否则是1,因为打开ssjson后GcExcel会计算A2单元格的值,而GcExcel的计算逻辑和Excel一致,所以结果是1


总结一下,如果您想要让SpreadJS、GcExcel、Excel三者表现一致,需要您
1. 在SpreadJS开启Excel兼容计算模式,重新保存sjs/ssjson文件
2. 为了兼容之前可能已经保存的未开启Excel兼容模式的sjs/ssjson文件,GcExcel导入文件后,强制重新计算一次:
  1. workbook.open(filepath);
  2. workbook.calculate();
复制代码



回复 使用道具 举报
低调的繁华
金牌服务用户   /  发表于:2025-3-20 11:25:14
板凳
Matthew.Xue 发表于 2025-3-20 09:53
您好,这里涉及到多个问题,我给您逐个解答:

1. SpreadJS、GcExcel、Excel在部分公式计算时本身就有区 ...

你好关于第4点我有个疑问,我使用   workbook.setEnableCalculation(true)开启自动计算后,A2的取值还是3,但是我使用workbook.calculate()后A2的取值是1了,这点的疑问是打开sjs文件后我们无论是否开启自动计算在getValue时公式都不会自动计算了吗?
  public static void readSjs() {
        Workbook workbook = new Workbook();
        workbook.open("./src/main/resources/函数验证.sjs", OpenFileFormat.Sjs);
        IWorksheet worksheet = workbook.getWorksheets().get("Sheet1");
        workbook.setEnableCalculation(true);
//        workbook.calculate();
        System.out.println(worksheet.getRange("A2").getValue());
        System.out.println(worksheet.getRange("A3").getValue());
        System.out.println(worksheet.getRange("A4").getValue());
    }
回复 使用道具 举报
Matthew.Xue
超级版主   /  发表于:2025-3-20 12:02:10
地板
低调的繁华 发表于 2025-3-20 11:25
你好关于第4点我有个疑问,我使用   workbook.setEnableCalculation(true)开启自动计算后,A2的取值还是3 ...

关于这一点,我需要和研发确认一下,按理说不管是ssjson还是sjs,导入后计算的逻辑都应该是相同的,请耐心等待。
回复 使用道具 举报
低调的繁华
金牌服务用户   /  发表于:2025-3-20 22:13:44
5#
Matthew.Xue 发表于 2025-3-20 12:02
关于这一点,我需要和研发确认一下,按理说不管是ssjson还是sjs,导入后计算的逻辑都应该是相同的,请耐 ...

好的 感谢
回复 使用道具 举报
Matthew.Xue
超级版主   /  发表于:2025-3-21 09:16:01
6#
本帖最后由 Matthew.Xue 于 2025-3-21 09:56 编辑

您好,研发那边有回复了,目前GcExcel对sjs和ssjson的处理的确有所不同,GcExcel会默认ssjson中存储的公式值是无效的,所以getValue的时候会重新计算;而GcExcel认为sjs的公式值是有效的,所以不会重算。
您可以通过一个option来控制打开ssjson后(注意,此配置仅对ssjson可用),是否重新计算:
  1. Workbook wb = new Workbook();
  2. DeserializationOptions deserializationOptions = new DeserializationOptions();
  3. deserializationOptions.setDoNotRecalculateAfterLoad(true); // 设置为true时,不会重新计算
  4. wb.open(path + "file.ssjson", deserializationOptions);
  5. IWorksheet sheet = wb.getActiveSheet();
  6. Object A1 = sheet.getRange("A1").getValue();
  7. System.out.println("SSJSON A1: " + A1);
复制代码
而针对sjs文件,您可以通过调用diry和calculate方法来重新计算公式结果,这一点和之前的讨论相似,只是多了dirty方法的调用,这是为了将所有公式值标记为无效数据,calculate时才会触发重算。之前之所以没有调用dirty也可以得到重算后1的结果,是因为您的文件开启了迭代计算,迭代计算开启后,GcExcel总是会重算,但是您无法保证所有的文件都开启了迭代计算功能,所以最好还是加上对dirty的调用。
  1. Workbook wb = new Workbook();
  2. wb.open(path + "calc.sjs");
  3. wb.dirty(); // 将公式的值设为无效
  4. wb.calculate(); // 强制重新计算
复制代码

回复 使用道具 举报
低调的繁华
金牌服务用户   /  发表于:2025-3-24 11:58:45
7#
Matthew.Xue 发表于 2025-3-21 09:16
您好,研发那边有回复了,目前GcExcel对sjs和ssjson的处理的确有所不同,GcExcel会默认ssjson中存储的公 ...

好的 十分感谢
回复 使用道具 举报
Matthew.Xue
超级版主   /  发表于:2025-3-24 12:15:47
8#

好的,那这边就先结贴了,有问题请发新帖~
回复 使用道具 举报
低调的繁华
金牌服务用户   /  发表于:2025-3-24 21:19:16
9#
Matthew.Xue 发表于 2025-3-24 12:15
好的,那这边就先结贴了,有问题请发新帖~

好的,感谢
回复 使用道具 举报
Matthew.Xue
超级版主   /  发表于:2025-3-25 09:43:46
10#
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部