我目前正在用Excel(.xlsx)提供的报告表来回想一下,我必须填写该表以补偿差旅费。该文档是一个庞然大物,大大降低了我的计算机的速度,因此,我决定构建一个小的“生成器”,因此不必打开.xlsx文件进行编辑。想法是在一个简单的.csv文件中提供所有信息,以编程方式读取此数据,然后使用Apache POI将所有数据填充到正确的位置。
我设法使简单的案例奏效了:
Workbook wb = WorkbookFactory.create(new File("in.xlsx"));
Sheet s = wb.getSheet("Sheet X");
s.getRow(16).getCell(12).setCellValue("some value");
...
FileOutputStream fileOut = new FileOutputStream("out.xlsx");
wb.write(fileOut);
fileOut.close();
不幸的是,报告表还包含复选框和单选按钮,这些复选框和单选按钮会自动设置某些字段,我不知道如何访问它们,更不用说以编程方式“单击”它们了。我已经开始阅读Excel生成的XML,并且在工作表XML中找到了<controls>
部分。我不允许共享文件,但其中包含以下复选框:
<control shapeId="8193" r:id="rId5" name="Check Box 1">
<controlPr defaultSize="0" autoFill="0" autoLine="0" autoPict="0">
<anchor moveWithCells="1">
<from><xdr:col>5</xdr:col><xdr:colOff>558800</xdr:colOff><xdr:row>16</xdr:row><xdr:rowOff>12700</xdr:rowOff></from>
<to><xdr:col>5</xdr:col><xdr:colOff>1028700</xdr:colOff><xdr:row>17</xdr:row><xdr:rowOff>0</xdr:rowOff></to>
</anchor>
</controlPr>
</control>
或单选按钮,例如:
<control shapeId="5121" r:id="rId6" name="Group Box 1">
<controlPr defaultSize="0" autoFill="0" autoPict="0">
<anchor moveWithCells="1">
<from><xdr:col>3</xdr:col><xdr:colOff>25400</xdr:colOff><xdr:row>16</xdr:row><xdr:rowOff>0</xdr:rowOff></from>
<to><xdr:col>7</xdr:col><xdr:colOff>12700</xdr:colOff><xdr:row>17</xdr:row><xdr:rowOff>0</xdr:rowOff></to>
</anchor>
</controlPr>
</control>
<control shapeId="5122" r:id="rId7" name="Option Button 2">
<controlPr defaultSize="0" autoFill="0" autoLine="0" autoPict="0">
<anchor moveWithCells="1">
<from><xdr:col>3</xdr:col><xdr:colOff>571500</xdr:colOff><xdr:row>16</xdr:row><xdr:rowOff>12700</xdr:rowOff></from>
<to><xdr:col>3</xdr:col><xdr:colOff>977900</xdr:colOff><xdr:row>17</xdr:row><xdr:rowOff>0</xdr:rowOff></to>
</anchor>
</controlPr>
</control>
...
(there are always three radio buttons per group)
通过读取.xslx文件的XML内容并使用我可以通过POI实际设置的设置,到目前为止,我发现了以下内容:
(Un-)勾选复选框将特定目标单元格设置为TRUE / FALSE,选择单选按钮会将特定目标单元格设置为某个值。在我的示例中,“锚点”似乎仅影响工作表设计,并且值的实际绑定和配置在xl / ctrlProps / *。xml文件中完成,您在提取.xlsx文件时会看到该文件。要找到正确的文件,您需要在xl/worksheets/_rels/*.rels
文件中找到控件的r:id,它再次指向ctrlProps
中的正确文件。
事实证明,这些绑定实际上是双向的,因此,当我再次打开Excel时,将TRUE写入引用的单元格也会选中该复选框。同样,将正确的数字写入目标单元格也会选择正确的单选按钮。但是,Apache POI仅在执行可能由控件触发的嵌入式代码时才具有有限的功能。结果,即使丢失的单元格仅包含简单的内联计算,我的程序更改似乎也不会传播到工作表的所有单元格。
正如@racraman指出的那样,可以从简单表达式中“重新计算”结果。
现在,我正在寻找以下两个主要问题的答案:
1)在.xlsx文件结构中的哪里找到VBA宏,以查看在Excel中单击即可执行的操作?
2)当涉及到“重新计算”时,为什么对于动态计算的单元格甚至需要这样做?评估结果也存储在文档中吗?我一直以为Excel会在首次打开时就计算所有内容,但我知道将它们存储起来可能会更快地加载时间。
我非常感谢任何指针。