java - 从 Excel 电子表格中读取手动插入的文本

标签 java python excel apache-poi xlrd

我有一个 .xlsx包含我的大学时间表的文件。我正在开发一个使用时间表的应用程序。但我不想将这个 Excel 电子表格中的时间表内容“复制”成更“对程序员友好”的格式,相反,我想编写一个程序/脚本来解析这个 .xlsx表并自动将其转换为我需要的格式(例如,在代码中的某些对象中)。
阅读电子表格的“正常”单元格对我来说没有问题。但是,创建此时间表文件的人不是简单地在每个单元格中输入 1 个文本条目,而是手动将一些单元格“划分”为“子单元格”,并在每个单元格中手动插入一些文本。这看起来像:fig1

How should this be interpreted: students are divided into 4 groups. At 15.20-16.50 only groups number 1 and 2 will have a specific class. At 17.00-18.30 only groups 1, 3, and 4 will have that class.


正如人们所看到的,这些“单元格”并不是真正的单元格——它们似乎是手动创建(“划分”)的,就像在图片中选择的文本一样。
问题是:我如何找到并阅读图片中的此类“单元格”(手动插入的文本组件) (最好也知道它们的位置,这样我不仅可以读取存在哪些类,还可以读取它们何时开始(时间在电子表格的最左侧说明)) ?
我尝试使用 python xlrd模块,但无法实现我所需要的。我在 上也没有取得任何成功 java Apache POI — 我只是找不到如何阅读这些文本条目。两种语言的解决方案,无论使用什么库和方法,对我来说都很好。

最佳答案

xls 和 xslx 都是专有格式。微软竭尽全力在法庭上解释 xslx 是开放的,但不幸的是,所涉及的法官中没有一位对计算机科学有任何重要的了解,而律师也知道这一点,所以不要被他们的误导性案件分散注意力。 XSLX 可以选择让“供应商”添加一个“自定义二进制 blob” block ,并且绝大多数不是最常见的、可以想象的最低级别的东西的 excel 功能都在这些二进制 blob 中。毫无疑问,这里发生的“将文本表格对象粘贴到单个单元格中”的事情就是这样。
Microsoft 从未发布任何关于这些二进制 blob 的文档,也没有发布任何可以解析它们的库。
因此,Apache POI、xlrd 和所有其他用于读取 XLS 文件的库并不明确要求在运行“库”的计算机上安装和运行 Excel(如果你有一个 linux-基于服务器!)基于逆向工程,这是一种可怕的格式。从字面上看 - 查找 Apache POI 的“HSSF”代表什么。官方没有,但在词源上,H 代表可怕。 (可怕的电子表格格式 - HSSF)。
这就是说:对不起 - 你可能不能。这不是 POI 或 xlrd 的错,而是微软的错。使用这种封闭的、专有的和未记录的格式来传输任何有意义的东西是不合适的。错误在于导致您现在陷入尝试编写软件来解析奇怪的excel文件的任何过程。
如果必须,很可能在 excel 中运行的脚本可以解开这个困惑并写出 csv 文件或 json 或文档格式的东西。或者,您可以用 C# 编写一些东西,但这只是将工作分担到 excel 中,因此,您仍然无法将此代码移植到其他平台。
Apache POI 确实为您提供了一种更底层方法的选项,您可以在其中读取二进制 blob。您可以尝试自己对“带有表格的单元格”中发生的任何事情进行逆向工程,但是 xlrd 团队和 Apache POI 团队都没有打扰,至少 POI 团队记录为说格式似乎被设计为混淆 - 这听起来像是一项需要你很多很多周的工作。
这让我回到了我之前建议的解决方案:除非花费数周时间构建一个非常脆弱的堆栈,需要一个完整的窗口和一个 excel 许可证,与人类行为的简单改变相比(不太可能),解决方案在于解决这个过程(例如,excel用于传输此信息的地址,或者至少使excel表比这件事更简单),而不是通过找出如何在java或python中阅读这个烂摊子。

关于java - 从 Excel 电子表格中读取手动插入的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64471849/

相关文章:

java - 为 Google 的 Android 滑动选项卡着色

python - Reportlab - 表格扩展到多个框架和页面

excel - 如何在excel vba中添加段落或中断

vba - 如何从 VBA 标准库中重载 IsEmpty() 等函数?

excel - 每个被叫号码的通话记录明细

Java DateTimeFormatter 在时区为 +0000 时添加 Z

java - 如何在 Spring Security 中的子域之间共享 session

python - 如何使用 pika 通过 Python 客户端连接到 RabbitMQ 集群?

java - 如何在 JPA 标准 API 中进行不同计数?

python - IPython 并行 LoadBalancedView GIL