1

我希望有人能帮我想出一个算法。

我对 Apache POI 还是很陌生,我被分配提出一个关于如何读取模板 (Excel) 并从数据本身中提取标题/列名的算法。

必须考虑以下事项:

  1. 一张 Excel 文件中可以有多个标题/列名。

  2. 标题本质上可以是水平的和/或垂直的。这意味着一张表中可能混合有垂直和水平标题。

  3. 标题不一定必须位于文件的第一行。那里可能有介绍或横幅图片。

  4. 系统必须允许任何类型的 Excel 格式,因此无法控制单元格的格式、命名约定等。

  5. 一些标题本质上是字母数字,这意味着它也包含数字。

  6. 一些单元格被合并为特定标题腾出空间。

非常欢迎任何想法和建议。如果您有进一步的说明,请告诉我。

4

2 回答 2

4

(我对 Apache 一无所知,但对 Excel 互操作工作有些了解)

如果要检测的工作表是您的,我建议命名这些标题单元格。(要在 Excel 中命名一个单元格,屏幕左上角有一个字段,通常会出现单元格坐标(如“A1”或“B2”等等......)。在那个地方输入一个名称,然后你将能够通过代码通过其名称识别该单元格。('Worksheet.Range("Name")' 是您通过代码获取这些单元格的地方)

要管理名称,请转到“插入 - 名称”或“公式 - 名称管理器”,具体取决于 Excel 的版本。

(就个人而言,我从不通过没有命名标题的代码使用工作表,然后我使用“偏移”来获取与这些标题相对应的数据单元格 - 这使我可以在以后自由编辑工作表而不会破坏代码)

如果工作表不是您的,那么您需要找出数据的范围。(最后一行和最后一列)然后检查包含所有已填充列的第一行,其中没有一个为空白。那是一个可能的水平标题。以及检查包含所有填充行的第一列。那是一个可能的垂直标题。

您还可以搜索完全空白的行和/或列以查找位于某些数据之后的标题,以防工作表包含多个水平标题或垂直标题。

您可以使用这些单元格的一些格式属性(例如 Range.Interior 或 Range.Font)来识别它们是否是标题(通常标题具有不同的格式、颜色、边框等)。

如果您确定没有数字标题,我的意思是,所有标题都包含文本,请检查单元格中的数据类型。如果都是字符串,则标题概率会增加。

即便如此,这是一件棘手的事情,如果工作表不遵循某种模式,有时其中一个可能会欺骗您的代码并带来错误的结果。如果允许,我建议在处理完成后添加人工验证以确认结果。

于 2013-03-20T12:02:52.023 回答
0

这个问题的解决方案包括取消其中两个自由。应用的此类约束将使这成为一个易于处理的问题。大多数这样的自由来自过度谨慎的思考。自由引用如下:-

标题本质上可以是水平的和/或垂直的。这意味着一张表中可能混合有垂直和水平标题。

通常,在需要以编程方式检测标题的 Excel 文件中不使用垂直标题。作为此类检测的主要、最常见且有时唯一的原因是上传/转换表格数据。

引入垂直标题时会发生有趣的事情:

  1. 它们成为形式的标签。这意味着此类表格用于数据输入而不是存储。来自此类表单的数据存储在数据的水平/列标题和行/垂直记录中。从而消除了对数据输入表的上传/转换的需要。
  2. Excel 设计为只有水平标题。垂直标题不再支持自动过滤器。
  3. 即使存在垂直标题,仍然可以引入顶部水平标题行以将标题本身标记为描述/类别。

保持真实,对于自动检测标题的核心需求,我们可以声明,一旦我们的要求表明标题只能以水平对齐方式放置,解决方案会变得稍微容易处理,但并非完全如此。

一些单元格被合并为特定标题腾出空间。

合并单元格是数据转换/上传的全部原因的毒药和诅咒。这是我在 Excel 和 SQL 杂耍的整个职业生涯中坚决拒绝服用的药丸。您可以将所有您想要的内容合并到我关心的所有内容中,但是您不会传递到我心爱的 SQL Server 中。

出于上述对所有合并和合并的偏见和恶意的原因。我恭敬地建议你也参加这门课程。

解决方案

在取消 2 项自由后坚持上述要求。伪算法(解决方案)是

  1. 以 cxr Excel 行为例。例如:200 x 201 行和列

  2. 使用内置公式(如 COUNTA,其内容具有非零长度)查找非空单元格的计数。每行中此类非空单元格的计数作为数据结构进行维护。

  3. 数据类型 ie:- Number, Date, String 也应该保持在上述能够表达以下内容的数据结构中:

    第 22 行包含
    30 个非空单元格,其中
    28 个是字母数字,
    1 个是日期,
    1 个是数字。

  4. 包含最大数量的此类非空单元格和最大字符串数的第一个特定行很可能是标题行。

将上述所有内容转换为任何给定语言的特定算法对于任何处于鼎盛时期的年轻开发人员来说都是一项艰巨的任务。

于 2021-05-16T09:26:10.057 回答