Linux / Unix 设计思想之 FLAT 原则
图片来源于 500px
何谓 FLAT 原则
即 使用纯文本来存储数据。为什么呢?因为这样可以使数据具有最大的可移植性。
遭遇问题
在使用 Apache POI 来生成 Excel 时,当修改 Excel 表单的名字时,导致保存后的 Excel 打开,图标数据丢失,打开报告错误:
原因是图表数据中有对 Excel 文件名的引用:
原因找到了,可是怎么去修复呢,完全不知道 POI 图表的哪个 API 能设置这个啊。这时候连万能的谷歌都不好使了,毕竟这个是非常小众的场景啊。
从放弃到再试
简单尝试了去修正图标对表单名的引用,但是因为找不到正确的 API,都无功而返。只好先把精力放在业务相关上,暂时不允许表单改名了,周末在家里想着,XLSX 不就是 OOXML 格式么,其实就是一个普通的 zip 格式啊,完全可以解压开来,然后去看看图表数据中对于表单名的引用是存储在哪里的。
然后全文搜索一下,马上就找到了位置了:
分析 XML 结构,寻找对应的 POI 的 API.
用 在线XML工具 分析一下 chart1.xml 的文档结构,如下:
发现文档名的位置在:chart->plotArea->barChart->ser->val->numRef->f 下面。然后就顺藤摸瓜,很快找到了对应的 API 了,成功完成表单名的改名动作。
/** * 修正图表中对于表单名字的引用。 * * @param sheet EXCEL表单。 * @param oldSheetName 旧的表单名字。 * @param newSheetName 新的表单名字。 */ public static void fixChartSheetNameRef(Sheet sheet, String oldSheetName, String newSheetName) { val drawing = sheet.getDrawingPatriarch(); if (!(drawing instanceof XSSFDrawing)) return; for (val chart : ((XSSFDrawing) drawing).getCharts()) { for (val barChart : chart.getCTChart().getPlotArea().getBarChartList()) { for (val ser : barChart.getSerList()) { val val = ser.getVal(); if (val == null) continue; val numRef = val.getNumRef(); if (numRef == null) continue; val f = numRef.getF(); if (f == null) continue; if (f.contains(oldSheetName)) { numRef.setF(f.replace(oldSheetName, newSheetName)); } } } } }
总结
因为刚刚回看了 Linux / Unix 设计思想,想到 XML 其实也是 FLAT 原则的一种体现。如果不是 OOXML 的格式,而是以前的 xls,那么就没那么容易肉眼去分析格式,去寻找对应的 API 了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: 代码的形状
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论