从 pdf 中提取表格信息、合并、解析、输出数据 您所在的位置:网站首页 从pdf里提取表格文字内容 从 pdf 中提取表格信息、合并、解析、输出数据

从 pdf 中提取表格信息、合并、解析、输出数据

2024-07-18 05:28| 来源: 网络整理| 查看: 265

从 pdf 中提取表格信息、合并、解析、输出 pdf 格式浅述word 文档 与 pdfpdf 文档撰写的优点与难点 从 pdf 中抽取表格所在的页从 pdf 中抽取表格合并表格、解析表格、生成输出数据进一步的反思用 perl 来完成文字处理

pdf 格式浅述

pdf 作为一种使用极为广泛的【可移植文件格式】,常用于各种用户手册及专业文档的撰写。可能很多人都认为 pdf 只是一些图片的打包合集,这其实是对 pdf 格式的一种误解。

作为专业的文档格式,pdf 中支持插入各种【图表、公式】等。完全使用图片来构建一个 pdf 仅仅使用了 pdf 中很小的一部分功能,且生成的 pdf 的内容不能直接复制。

word 文档 与 pdf

也许很多人在日常办公中经常接触到 pdf ,经常扫描文件生成扫描版 pdf。word 文档可能还经常撰写,但 pdf 却从来没有自己编写过。实际上对于专业性要求不高的内容, word 文档的撰写确实要比 pdf 文档更容易,图形化的排版过程隐藏了背后复杂的命令,更方便用户使用。

word 文档的优点一目了然,可在专业的文档撰写中 word 文档却常常被诟病。实际上,使用 word 排版专业文档并不容易。每次排版设定的格式可复用性不高,保存的文件格式也极不便于进行版本控制。

pdf 文档撰写的优点与难点

pdf 文档弥补了 word 的上述缺陷,但 pdf 撰写的门槛却比 word 高出许多,这也就意味着你几乎不太可能只【点点鼠标】就能排版出一篇文章,你需要对排版系统进行学习,了解各种命令。虽然这种学习会耗费许多的时间与精力,可学到的知识能够一直使用下去,同时你对排版本身的各种原理也能有更进一步的认识。

使用过 Latex 排版系统的人可能对上面的描述有切身的体会。使用 Latex 来撰写一篇 pdf 文档时,你需要用到许多的宏与命令来对文档格式进行精细的控制,这比 word 中点点鼠标就能排版更加困难,也更加接近排版本身。

我不对排版系统进行更进一步的叙述,感兴趣的读者可以搜索相关的网页进一步了解。

从 pdf 中抽取表格所在的页

常见的图文混排 pdf 中,表格零散的分布在 pdf 文档的各个部分。我们需要从 pdf 文档中将需要抽取的表格所在的页【抽取】出来。这一过程可以通过一些高级的 【pdf 编辑器】来完成。我没有使用 【pdf 编辑器】,我使用了一种命令行工具——【pdftk】来完成了这一任务。下面是相关的操作命令:

sudo apt-get install pdftk pdftk in.pdf cat 50-60 output out.pdf

命令说明文档请 man pdftk 。

从 pdf 中抽取表格

从一个大的 pdf 中抽取出来表格所在的页后,我们就可以从生成的 pdf 中抽取表格内容。注意抽出来的内容不能是扫描生成的图片,如果是图片将抽取失败!!!

pdf 格式有自己的文件格式规范,这一规范能够在网上找到。从 pdf 中抽取信息的参考便是这一文件格式规范。在这里我并没有尝试自己去撰写一个抽取工具,我直接使用了网页搜索得到的方法。

我使用 【tabula】 来从 pdf 中抽取表格信息,关于此模块的安装使用详见——【使用 tabula 脚本从 pdf 中提取表格信息为 python 数据帧】。

在安装使用过程中有如下【注意事项】:

python-numpy 版本问题

如果你的系统中安装了多个版本的 【python-numpy】,请参考 【如何升级 numpy】 中的回答来解决。

java 环境依赖问题

由于我已经安装并配置了 java 环境,我没有遇到这一问题。遇到这个问题的读者请自行 google、百度解决。

【tabula】 可以将表格信息输出为四种格式:

1. python DataFrame 2. json 3. tsv 4. csv

在这里我使用 csv 作为输出格式。注意当待抽取的 pdf 文档有多页时,需要设定 pages 属性为 “all”’。

我使用 【tabula】 从下图中的 pdf 表格中提取信息。 引脚复用功能提取的信息中的部分内容如下:

176,Pin,DEFAUL,ALT0,ALT1,ALT2,ALT3,ALT4,ALT5,ALT6,ALT7 VFBGA,Name,T, C1,PTB3,LPADC0_,LPADC0_,PTB3/,LPSPI0_,LPUART1,I2S0_TX_,FB_AD10,TPM0_C,— “”,SE0,SE0,RF0_EXT,PCS3,TX,FS,H1, “”,OSC_E, “”,N, C2,PTB4/,LPADC0,LPADC0,PTB4/,LPSPI0_,LPUART1,I2S0_TX_,FB_AD9,TPM0_C,— “”,LLWU_P6,SE1,SE1,LLWU_P6,SCK,CTS,BCLK,H2, “”,/, “”,RF0_RF, “”,OFF/, “”,RF0_DFT, “”,RESET, D2,PTB5,DISABLE,—,PTB5/,LPSPI0,LPUART1,I2S0_MC,FB_AD8,TPM0_C,— “”,D,RF0_ACT,SOUT,_RTS,LK,H3, “”,IVE,

上面的输出有点奇怪,它与表格的内容看上去并不一致。如果你仔细观察,你会发现当表格中单行的数据由多个行组成时,每一个行都被单独的提取出来了,这是 【tabula】 的一个缺陷,不过这并不致命,只要信息是正确的,那么编写代码将数据合并起来就行了。

合并表格、解析表格、生成输出数据

从上面抽取出来的表格信息中每一行的不同项之间通过逗号分割,使用 awk 来处理这种具有多个字段的信息相对容易,我就使用 awk 脚本来合并被分开的行,并完成【解析与输出】的任务。

代码如下:

#!/usr/bin/gawk -f BEGIN { parse_and_generate() exit 0 } function make_output_result(hash_table, buffer, gpio_name) { gpio_name = hash_table["GPIONAME"] if (hash_table["PIN_MUX_ALT0"] != "") { buffer = sprintf("#define %8s_%-26s%s(%s)\n\n", gpio_name, hash_table["PIN_MUX_ALT0"], "RV32M1_VEGA_PIN_MUX", "PIN_MUX_ALT0") } if (hash_table["PIN_MUX_ASGPIO"] != "") { buffer = buffer sprintf("#define %8s_%-26s%s(%s)\n\n", gpio_name, "GPIO", "RV32M1_VEGA_PIN_MUX", "PIN_MUX_AS_GPIO") } if (hash_table["PIN_MUX_ALT2"] != "") { buffer = buffer sprintf("#define %8s_%-26s%s(%s)\n\n", gpio_name, hash_table["PIN_MUX_ALT2"], "RV32M1_VEGA_PIN_MUX", "PIN_MUX_ALT2") } if (hash_table["PIN_MUX_ALT3"] != "") { buffer = buffer sprintf("#define %8s_%-26s%s(%s)\n\n", gpio_name, hash_table["PIN_MUX_ALT3"], "RV32M1_VEGA_PIN_MUX", "PIN_MUX_ALT3") } if (hash_table["PIN_MUX_ALT4"] != "") { buffer = buffer sprintf("#define %8s_%-26s%s(%s)\n\n", gpio_name, hash_table["PIN_MUX_ALT4"], "RV32M1_VEGA_PIN_MUX", "PIN_MUX_ALT4") } if (hash_table["PIN_MUX_ALT5"] != "") { buffer = buffer sprintf("#define %8s_%-26s%s(%s)\n\n", gpio_name, hash_table["PIN_MUX_ALT5"], "RV32M1_VEGA_PIN_MUX", "PIN_MUX_ALT5") } if (hash_table["PIN_MUX_ALT6"] != "") { buffer = buffer sprintf("#define %8s_%-26s%s(%s)\n\n", gpio_name, hash_table["PIN_MUX_ALT6"], "RV32M1_VEGA_PIN_MUX", "PIN_MUX_ALT6") } if (hash_table["PIN_MUX_ALT7"] != "") { buffer = buffer sprintf("#define %8s_%-26s%s(%s)\n\n", gpio_name, hash_table["PIN_MUX_ALT7"], "RV32M1_VEGA_PIN_MUX", "PIN_MUX_ALT7") } buffer = buffer "\n\n" return buffer } function eval_string(buffer, num, result_buffer, split_array, hash_table, i, j, len) { for (i = 1; i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有