提取PDF数据:Documents for PDF ( GcPdf )
在当今数据驱动的世界中,从 PDF 文档中无缝提取结构化表格数据已成为开发人员的一项关键任务。借助GrapeCity Documents for PDF ( GcPdf ),您可以使用 C# 以编程方式轻松解锁这些 PDF 中隐藏的信息宝藏。
考虑一下 PDF(最常用的文档格式之一)的流行程度,以及它的表格中可以包含的大量数据。公司和组织一直在使用 PDF 文档来查看财务分析、股票趋势、联系方式等。现在,想象一下多年来检查季度报告的情况,其中数据的积累占据了中心位置。
从这些报告中获取数据最初看起来可能很容易(复制/粘贴)。尽管如此,由于 PDF 文件的结构,简单的复制和粘贴无需大量操作和修改即可获得表格数据的情况很少见。
再加上从许多其他文档复制和粘贴的可能性,这是一个漫长的一天(甚至一周或更长时间,取决于所需数据!)的秘诀。有效地处理此类需求需要一个能够自动执行此过程的工具,而 C# .NET GcPdf API 库是完成这项工作的完美工具!
本文适用于希望减少收集数据所需时间并提高数据收集过程准确性的开发人员。这些示例将帮助开发人员了解 GcPdf 工具,以便访问 PDF 文件中的表格并提取表格数据以便根据需要导出为 CSV 文件或其他格式(例如 XLSX)。
有关 PDF 文档中表格的重要信息
表格与 PDF 文件格式非常相似,是一种几乎流行的数据呈现方式。尽管如此,有必要了解 PDF 文档本质上缺乏表格的概念。换句话说,您在 PDF 中看到的表格纯粹是视觉元素。
这些 PDF“表格”与我们在 MS Excel 或 MS Word 等应用程序中常见的表格不同。相反,它们是通过负责在特定位置渲染文本和图形的运算符组合来构造的,类似于表格结构。
这意味着行、列和单元格的传统概念对于 PDF 文件来说是陌生的,没有底层代码组件来帮助识别这些元素。那么,让我们深入研究一下 GcPdf 的 C# API 库如何帮助我们实现这一任务!
如何使用 C# 以编程方式从 PDF 文档中提取表格数据
- 创建包含 GcPdf 的 .NET Core 控制台应用程序
- 加载包含数据表的示例 PDF
- 定义表识别参数
- 获取表数据
- 将提取的 PDF 表数据保存到另一种文件类型 (CSV)
- 奖励:将导出的 PDF 表格数据格式化为 Excel (XLSX) 文件
请务必下载示例应用程序 并尝试本博客文章中描述的用例场景和代码片段的详细实现。
创建包含 GcPdf 的 .NET Core 控制台应用程序
创建 .NET Core 控制台应用程序,右键单击“依赖项”,然后选择“管理 NuGet 包”。在“浏览”选项卡下,搜索“GrapeCity.Documents.Pdf”并单击“安装”。

安装时,您将收到“许可证接受”对话框。单击“我接受”继续。

在程序文件中,导入以下命名空间:
using System.Text;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Pdf.Recognition;
using System.Linq;
加载包含数据表的示例 PDF
通过初始化GcPdfDocument 构造函数来加载将要解析的 PDF 文档来创建新的 PDF 文档。调用 GcPdfDocument 的 Load 方法来加载包含数据表的原始 PDF 文档。
using (var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "zugferd-invoice.pdf")))
{// Initialize GcPdfvar pdfDoc= new GcPdfDocument();// Load a PDF documentpdfDoc.Load(fs);
}
在此示例中,我们将使用此 PDF:

定义表识别参数
实例化RectangleF 类的新实例并定义 PDF 文档中的表格边界。
const float DPI = 72;
using (var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "zugferd-invoice.pdf")))
{// Initialize GcPdfvar pdfDoc= new GcPdfDocument();// Load a PDF documentpdfDoc.Load(fs);// The approx table bounds:var tableBounds = new RectangleF(0, 2.5f * DPI, 8.5f * DPI, 3.75f * DPI);
}
为了帮助在定义的参数内识别表格,我们使用TableExtractOptions类,允许我们微调表格识别,考虑表格格式的特性。TableExtractOptions 是一个参数,用于指定表格式选项,例如列宽、行高以及行或列之间的距离。
// TableExtractOptions allow to fine-tune table recognition accounting for
// specifics of the table formatting:
var tableExtrctOpt = new TableExtractOptions();
var GetMinimumDistanceBetweenRows = tableExtrctOpt.GetMinimumDistanceBetweenRows;// In this particular case, we slightly increase the minimum distance between rows
// to make sure cells with wrapped text are not mistaken for two cells:
tableExtrctOpt.GetMinimumDistanceBetweenRows = (list) =>
{var res = GetMinimumDistanceBetweenRows(list);return res * 1.2f;
};
获取 PDF 的表格数据
创建一个列表来保存 PDF 页面中的表格数据。
// CSV: list to keep table data from all pages:
var data = new List<List<string>>();
使用 定义的表边界(在上一步中定义)调用GetTable 方法,以使 GcPdf 搜索指定矩形内的表。
for (int i = 0; i < pdfDoc.Pages.Count; ++i)
{// Get the table at the specified bounds:var itable = pdfDoc.Pages[i].GetTable(tableBounds, tableExtrctOpt);
}
使用ITable.GetCell(rowIndex, colIndex) 方法访问表中的每个单元格。使用 Rows.Count 和 Cols.Count 属性循环访问提取的表格单元格。
for (int i = 0; i < pdfDoc.Pages.Count; ++i)
{// Get the table at the specified bounds:var itable = pdfDoc.Pages[i].GetTable(tableBounds, tableExtrctOpt);if (itable != null){for (int row = 0; row < itable.Rows.Count; ++row){// CSV: add next data row ignoring headers:if (row > 0)data.Add(new List<string>());for (int col = 0; col < itable.Cols.Count; ++col){var cell = itable.GetCell(row, col);if (cell == null && row > 0)data.Last().Add("");else{if (cell != null && row > 0)data.Last().Add($"\"{cell.Text}\"");}}}}
}
将提取的 PDF 表数据保存到另一种文件类型 (CSV)
对于此步骤,我们必须首先添加对“System.Text.Encoding.CodePages”NuGet 包引用的引用。
然后,为了保存上一步中从变量中提取的 PDF 表数据,我们将使用 File 类 并调用其 AppendAllLines 方法。
for (int i = 0; i < pdfDoc.Pages.Count; ++i)
{// Get the table at the specified bounds:var itable = pdfDoc.Pages[i].GetTable(tableBounds, tableExtrctOpt);if (itable != null){for (int row = 0; row < itable.Rows.Count; ++row){// CSV: add next data row ignoring headers:if (row > 0)data.Add(new List<string>());for (int col = 0; col < itable.Cols.Count; ++col){var cell = itable.GetCell(row, col);if (cell == null && row > 0)data.Last().Add("");else{if (cell != null && row > 0)data.Last().Add($"\"{cell.Text}\"");}} }}
}
数据现在将以 CSV 文件形式提供:
|
|
|
奖励:将导出的 PDF 表格数据格式化为 Excel (XLSX) 文件
尽管数据现在以易于读取和操作的格式提供,但它是以 CSV 文件格式的原始格式保存的。为了更好地利用数据并使分析更容易进行,请使用 GrapeCity Documents for Excel (GcExcel) .NET 版本和 C# 将 CSV 文件加载到 Excel (XLSX) 文件中,并对提取的数据应用样式和格式。
要使用 GcExcel,请将NuGet 包“GrapeCity.Documents.Excel”添加到项目中并添加其命名空间。
using GrapeCity.Documents.Excel;
初始化 GcExcel 工作簿实例并使用Open方法加载 CSV 文件。
var workbook = new GrapeCity.Documents.Excel.Workbook();workbook.Open($@"{fileName}", OpenFileFormat.Csv);
获取提取数据的范围并包装单元格范围,对列应用自动调整大小,并应用带条件背景颜色的样式。
IWorksheet worksheet = workbook.Worksheets[0];
IRange range = worksheet.Range["A2:E10"];// wrapping cell content
range.WrapText = true;// styling column names
worksheet.Range["A1"].EntireRow.Font.Bold = true;// auto-sizing range
worksheet.Range["A1:E10"].AutoFit();// aligning cell content
worksheet.Range["A1:E10"].HorizontalAlignment = HorizontalAlignment.Center;
worksheet.Range["A1:E10"].VerticalAlignment = VerticalAlignment.Center;// applying conditional format on UnitPrice
IColorScale twoColorScaleRule = worksheet.Range["E2:E10"].FormatConditions.AddColorScale(ColorScaleType.TwoColorScale);twoColorScaleRule.ColorScaleCriteria[0].Type = ConditionValueTypes.LowestValue;
twoColorScaleRule.ColorScaleCriteria[0].FormatColor.Color = Color.FromArgb(255, 229, 229);twoColorScaleRule.ColorScaleCriteria[1].Type = ConditionValueTypes.HighestValue;
twoColorScaleRule.ColorScaleCriteria[1].FormatColor.Color = Color.FromArgb(255, 20, 20);Thread.Sleep(1000);
最后,使用Save方法将工作簿保存为 Excel 文件:
workbook.Save("ExtractedData_Formatted.xlsx");
如您所见,使用 C# 和 GcPdf,开发人员可以以编程方式将 PDF 表格数据提取到另一个文件(如 CSV),然后使用 GcExcel,可以将数据转换为风格化和格式化的 Excel XLSX 文件,以便于数据分析:
|
|
|
|
GrapeCity 的 .NET PDF API 库
将此 .NET PDF 服务器端 API 集成到桌面或基于 Web 的应用程序中,使开发人员能够完全控制 PDF - 快速生成文档、提高内存效率且无依赖性。
相关文章:
提取PDF数据:Documents for PDF ( GcPdf )
在当今数据驱动的世界中,从 PDF 文档中无缝提取结构化表格数据已成为开发人员的一项关键任务。借助GrapeCity Documents for PDF ( GcPdf ),您可以使用 C# 以编程方式轻松解锁这些 PDF 中隐藏的信息宝藏。 考虑一下 PDF(最常用的文档格式之一…...
adb连接切换到模拟器端口
查看连接状态 adb devices出现以下情况 C:\Users\22560>adb devices List of devices attached 127.0.0.1:5555 offline emulator-5554 device可以发现我们想要连接的雷电模拟器的5555端口目前没有连接,只有emulator-5554被连接了,此时我们需要关…...
为何每个开发者都在谈论Go?
目录 一、引言Go的历史回顾关键时间节点 使用场景Go的语言地位技术社群与企业支持资源投入和生态系统 二、简洁的语法结构基本组成元素变量声明与初始化代码示例 类型推断函数与返回值代码示例输出 接口与结构体:组合而非继承错误处理:明确而不是异常小结…...
【Leetcode】 501. 二叉搜索树中的众数
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数,可以按 任意顺序 返回。 假定 BST 满足如下定义…...
怎样给Ubuntu系统安装vmware-tools
首先我要告诉你:Ubuntu无法安装vmware-tools,之所以这么些是因为我一开始也是这样认为的,vmware-tools是给Windows系统准备的我认为,毕竟Windows占有率远远高于Linux,这也可以理解。 那么怎么样实现Ubuntu虚拟机跟Wind…...
DDS信号发生器波形发生器VHDL
名称:DDS信号发生器波形发生器 软件:Quartus 语言:VHDL 要求: 在EDA平台中使用VHDL语言为工具,设计一个常见信号发生电路,要求: 1. 能够产生锯齿波,方波,三角波&…...
Python3操作SQLite3创建表主键自增长|CRUD基本操作
Win11查看安装的Python路径及安装的库 Python PEP8 代码规范常见问题及解决方案 Python3操作MySQL8.XX创建表|CRUD基本操作 Python3操作SQLite3创建表主键自增长|CRUD基本操作 anaconda3最新版安装|使用详情|Error: Please select a valid Python interpreter Python函数绘…...
B. Comparison String
题目: 样例: 输入 4 4 <<>> 4 >><< 5 >>>>> 7 <><><><输出 3 3 6 2 思路: 由题意,条件是 又因为要使用尽可能少的数字,这是一道贪心题,所以…...
python端口扫描
扫描所有端口 import socket, threading, os, timedef port_thread(ip, start, step, timeout):for port in range(start, start step):s socket.socket()s.settimeout(timeout)try:s.connect((ip, port))print(f"port[{port}] 可用")except Exception as e:# pri…...
国庆第二天
#include<th.h>#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__",__LINE__);\perror(msg);\ }while(0)#define PORT 6666 #define IP "192.168.2.3"//键盘输入事件 int serverkeyboard(fd_set readfds) {char buf[128] "";int sndfd -…...
Java安全之servlet内存马分析
目录 前言 什么是中间键 了解jsp的本质 理解servlet运行机制 servlet的生命周期 Tomcat总体架构 查看Context 的源码 servlet内存马实现 参考 前言 php和jsp一句话马我想大家都知道,早先就听小伙伴说过一句话木马已经过时了,现在是内存马的天下…...
2023年第二十届中国研究生数学建模竞赛总结与分享
今天是国庆节,祝祖国繁荣富强。正好也学习不下去,就想着写写博客,总结一下自己在参加2023年第20届中国研究生数学建模比赛的一些感受。 目录 1.基本介绍 2.比赛分享 1.基本介绍 1. 竞赛时间:竞赛定于2023年9月22日8:00至2023年9…...
Web前端-Vue2+Vue3基础入门到实战项目-Day1(初始Vue, Vue指令, 小黑记事本)
Web前端-Vue2Vue3基础入门到实战项目-Day1 Vue快速上手创建一个Vue实例插值表达式Vue响应式特性 Vue指令指令初识 和 v-htmlv-show 和 v-ifv-else 和 v-else-ifv-on内联语句methods处理函数调用传参 v-bind案例 - 波仔的学习之旅v-forv-for基本使用案例 - 小黑的书架v-for的key…...
Sentinel学习(2)——sentinel的使用,引入依赖和配置 对消费者进行流控 对生产者进行熔断降级
前言 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 本篇博客介绍sentinel的使用&#x…...
springboot 简单配置mongodb多数据源
准备工作: 本地mongodb一个创建两个数据库 student 和 student-two 所需jar包: # springboot基于的版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>&l…...
西门子S7-1200使用LRCF通信库与安川机器人进行EthernetIP通信的具体方法示例
西门子S7-1200使用LRCF通信库与安川机器人进行EthernetIP通信的具体方法示例 准备条件: PLC:S7-1200 1214C DC/DC/DC 系统版本4.5及以上。 机器人控制柜:安川YRC1000。 软件:TIA V17 PLC做主站,机器人做从站。 具体方法可参考以下内容: 使用的库文件为西门子 1200系列…...
pytorch第一天(tensor数据和csv数据的预处理)lm老师版
tensor数据: import torch import numpyx torch.arange(12) print(x) print(x.shape) print(x.numel())X x.reshape(3, 4) print(X)zeros torch.zeros((2, 3, 4)) print(zeros)ones torch.ones((2,3,4)) print(ones)randon torch.randn(3,4) print(randon)a …...
CSP-J第二轮试题-2021年-1.2题
文章目录 参考:总结 [CSP-J 2021] 分糖果题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 样例 #3样例输入 #3样例输出 #3 提示答案1答案2-优化 [CSP-J 2021] 插入排序题目描述输入格式输出格式样例 #1样例输入 #1样…...
怒刷LeetCode的第16天(Java版)
目录 第一题 题目来源 题目内容 解决方法 方法一:迭代 方法二:模拟 方法三:循环模拟 方法四:传递 第二题 题目来源 题目内容 解决方法 方法一:回溯 方法二:枚举优化 第三题 题目来源 题目…...
让大脑自由
前言 作者写这本书的目的是什么? 教会我们如何让大脑更好地为自己工作。 1 大脑的运行机制是怎样的? 大脑的基本运行机制是神经元之间通过突触传递信息,神经元的兴奋和抑制状态决定了神经网络的运行和信息处理,神经网络可以通过…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...

原版PDF
在 CSV 文件中提取 PDF 表数据
原版PDF
在 CSV 文件中提取 PDF 表数据