当前位置: 首页 > news >正文

提取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 文档中提取表格数据

  1. 创建包含 GcPdf 的 .NET Core 控制台应用程序
  2. 加载包含数据表的示例 PDF
  3. 定义表识别参数
  4. 获取表数据
  5. 将提取的 PDF 表数据保存到另一种文件类型 (CSV)
  6. 奖励:将导出的 PDF 表格数据格式化为 Excel (XLSX) 文件

请务必下载示例应用程序 并尝试本博客文章中描述的用例场景和代码片段的详细实现。

创建包含 GcPdf 的 .NET Core 控制台应用程序

创建 .NET Core 控制台应用程序,右键单击“依赖项”,然后选择“管理 NuGet 包”。在“浏览”选项卡下,搜索“GrapeCity.Documents.Pdf”并单击“安装”。

PDF NuGet

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

在程序文件中,导入以下命名空间:

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

在 CSV 文件中提取 PDF 表数据

奖励:将导出的 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 文件,以便于数据分析:

原版PDF

在 CSV 文件中提取 PDF 表数据

格式化 Excel XLSX 文件

GrapeCity 的 .NET PDF API 库

将此 .NET PDF 服务器端 API 集成到桌面或基于 Web 的应用程序中,使开发人员能够完全控制 PDF - 快速生成文档、提高内存效率且无依赖性。

相关文章:

提取PDF数据:Documents for PDF ( GcPdf )

在当今数据驱动的世界中&#xff0c;从 PDF 文档中无缝提取结构化表格数据已成为开发人员的一项关键任务。借助GrapeCity Documents for PDF ( GcPdf )&#xff0c;您可以使用 C# 以编程方式轻松解锁这些 PDF 中隐藏的信息宝藏。 考虑一下 PDF&#xff08;最常用的文档格式之一…...

adb连接切换到模拟器端口

查看连接状态 adb devices出现以下情况 C:\Users\22560>adb devices List of devices attached 127.0.0.1:5555 offline emulator-5554 device可以发现我们想要连接的雷电模拟器的5555端口目前没有连接&#xff0c;只有emulator-5554被连接了&#xff0c;此时我们需要关…...

为何每个开发者都在谈论Go?

目录 一、引言Go的历史回顾关键时间节点 使用场景Go的语言地位技术社群与企业支持资源投入和生态系统 二、简洁的语法结构基本组成元素变量声明与初始化代码示例 类型推断函数与返回值代码示例输出 接口与结构体&#xff1a;组合而非继承错误处理&#xff1a;明确而不是异常小结…...

【Leetcode】 501. 二叉搜索树中的众数

给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;找出并返回 BST 中的所有 众数&#xff08;即&#xff0c;出现频率最高的元素&#xff09;。 如果树中有不止一个众数&#xff0c;可以按 任意顺序 返回。 假定 BST 满足如下定义&#xf…...

怎样给Ubuntu系统安装vmware-tools

首先我要告诉你&#xff1a;Ubuntu无法安装vmware-tools&#xff0c;之所以这么些是因为我一开始也是这样认为的&#xff0c;vmware-tools是给Windows系统准备的我认为&#xff0c;毕竟Windows占有率远远高于Linux&#xff0c;这也可以理解。 那么怎么样实现Ubuntu虚拟机跟Wind…...

DDS信号发生器波形发生器VHDL

名称&#xff1a;DDS信号发生器波形发生器 软件&#xff1a;Quartus 语言&#xff1a;VHDL 要求&#xff1a; 在EDA平台中使用VHDL语言为工具&#xff0c;设计一个常见信号发生电路&#xff0c;要求&#xff1a; 1. 能够产生锯齿波&#xff0c;方波&#xff0c;三角波&…...

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

题目&#xff1a; 样例&#xff1a; 输入 4 4 <<>> 4 >><< 5 >>>>> 7 <><><><输出 3 3 6 2 思路&#xff1a; 由题意&#xff0c;条件是 又因为要使用尽可能少的数字&#xff0c;这是一道贪心题&#xff0c;所以…...

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一句话马我想大家都知道&#xff0c;早先就听小伙伴说过一句话木马已经过时了&#xff0c;现在是内存马的天下…...

2023年第二十届中国研究生数学建模竞赛总结与分享

今天是国庆节&#xff0c;祝祖国繁荣富强。正好也学习不下去&#xff0c;就想着写写博客&#xff0c;总结一下自己在参加2023年第20届中国研究生数学建模比赛的一些感受。 目录 1.基本介绍 2.比赛分享 1.基本介绍 1. 竞赛时间&#xff1a;竞赛定于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 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 本篇博客介绍sentinel的使用&#x…...

springboot 简单配置mongodb多数据源

准备工作&#xff1a; 本地mongodb一个创建两个数据库 student 和 student-two 所需jar包&#xff1a; # 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数据&#xff1a; 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题

文章目录 参考&#xff1a;总结 [CSP-J 2021] 分糖果题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 样例 #3样例输入 #3样例输出 #3 提示答案1答案2-优化 [CSP-J 2021] 插入排序题目描述输入格式输出格式样例 #1样例输入 #1样…...

怒刷LeetCode的第16天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;迭代 方法二&#xff1a;模拟 方法三&#xff1a;循环模拟 方法四&#xff1a;传递 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;回溯 方法二&#xff1a;枚举优化 第三题 题目来源 题目…...

让大脑自由

前言 作者写这本书的目的是什么&#xff1f; 教会我们如何让大脑更好地为自己工作。 1 大脑的运行机制是怎样的&#xff1f; 大脑的基本运行机制是神经元之间通过突触传递信息&#xff0c;神经元的兴奋和抑制状态决定了神经网络的运行和信息处理&#xff0c;神经网络可以通过…...

Arcgis克里金插值报错:ERROR 010079: 无法估算半变异函数。 执行(Kriging)失败。

Arcgis克里金插值报错&#xff1a;ERROR 010079: 无法估算半变异函数。 执行(Kriging)失败。 问题描述&#xff1a; 原因&#xff1a; shape文件的问题&#xff0c;此图可以看出&#xff0c;待插值的点有好几个都超出了地理范围之外&#xff0c;这个不知道是坐标系配准的问…...

Docker Compose安装

title: “Docker Compose安装” createTime: 2022-01-04T19:08:1508:00 updateTime: 2022-01-04T19:08:1508:00 draft: false author: “name” tags: [“docker”,“docker-compose”] categories: [“install”] description: “测试的” docker-compose安装步骤 1.下载 u…...

机器人过程自动化(RPA)入门 7. 处理用户事件和助手机器人

在UiPath中,有两种类型的Robot用于自动化任何流程。一个是后台机器人,它在后台工作。它独立工作,这意味着它不需要用户的输入或任何用户交互。另一个是前台机器人,也被称为助理机器人。 本章介绍前台机器人。在这里,我们将了解自动化过程中通过简单按键、单击鼠标等触发事…...

在linux下预览markdown的方法,转换成html和pdf

背景 markdown是一种便于编写和版本控制的格式&#xff0c;但却不便于预览——特别是包含表格等复杂内容时&#xff0c;单纯的语法高亮是远远不够的——这样就不能边预览边调整内容&#xff0c;需要找到一种预览方法。 思路 linux下有个工具&#xff0c;叫pandoc&#xff0c…...

AIOT入门指南:探索人工智能与物联网的交汇点

AIOT入门指南&#xff1a;探索人工智能与物联网的交汇点 1. 引言 随着技术的快速发展&#xff0c;人工智能&#xff08;AI&#xff09;和物联网&#xff08;IoT&#xff09;已经成为当今最热门的技术领域。当这两个领域交汇时&#xff0c;我们得到了AIOT - 一个结合了AI的智能…...

CCC数字钥匙设计【NFC】 --车主配对流程介绍

1、车主配对流程介绍 车主配对流程可以通过车内NFC进行&#xff0c;若支持UWB测距&#xff0c;也可以通过蓝牙/UWB进行&#xff0c;本文主要介绍通过NFC进行车主配对的流程。 整个配对流程相对较为复杂&#xff0c;本文主要梳理整体的步骤流程&#xff0c;其中的每个细节流程未…...

一站式开源持续测试平台 MerterSphere 之测试跟踪操作详解

一、MeterSphere平台介绍 MeterSphere是一站式的开源持续测试平台&#xff0c;遵循 GPL v3 开源许可协议&#xff0c;涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&#xff0c;全面兼容JMeter、Selenium 等主流开源标准&#xff0c;有效助力开发和测试团队充分利用云弹性进…...

自然语言处理状况简介

一、说明 自然语言处理已经进入大模型时代&#xff0c;然而从业人员必须了解整个知识体系、发展过程、知识结构&#xff0c;应用范围等一系列知识。本篇将报道此类概况。 二、自然语言处理简介 自然语言处理&#xff0c;或简称NLP&#xff0c;是处理和转换文本的计算机科学学科…...

python爬虫基于管道持久化存储操作

文章目录 基于管道持久化存储操作scrapy的使用步骤1.先转到想创建工程的目录下&#xff1a;cd ...2.创建一个工程3.创建之后要转到工程目录下4.在spiders子目录中创建一个爬虫文件5.执行工程setting文件中的参数 基于管道持久化存储的步骤&#xff1a;持久化存储1&#xff1a;保…...

【MySQL】数据类型(二)

文章目录 一. char字符串类型二. varchar字符串类型2.1 char和varchar比较 三. 日期和时间类型四. enum和set类型4.1 set的查询 结束语 一. char字符串类型 char (L) 固定长度字符串 L是可以存储的长度&#xff0c;单位是字符&#xff0c;最大长度是255 MySQL中的字符&#xff…...

素材网站/搜索优化师

///代码还存在问题&#xff0c;稍后想一下/ 题目描述&#xff1a; * 小C在做一种特殊的服务器负载测试&#xff0c;对于一个请求队列中的请求&#xff0c; * 每一个请求都有一个负荷值&#xff0c;为了保证服务器稳定&#xff0c;请求队列 * 中的请求负荷必须按照先递增后递…...

企业网站升级/国外免费网站建设

题目描述: (1)数组中占比超过一半的元素称之为主要元素。给定一个整数数组&#xff0c;找到它的主要元素。若没有&#xff0c;返回-1。 示例 1&#xff1a; 输入&#xff1a;[1,2,5,9,5,9,5,5,5] 输出&#xff1a;5示例 2&#xff1a; 输入&#xff1a;[3,2] 输出&#xff1a;-…...

wordpress插件聊天室小人/郑州seo推广优化

红色来源于山脉&#xff0c;象征着狂躁、愤怒、混乱&#xff0c;血雨腥风&#xff0c;电光火石。蓝色来源于海岛&#xff0c;象征着控制、幻觉、诡计&#xff0c;运筹帷幄&#xff0c;谋定后动。绿色来源于树林&#xff0c;象征着生命、蛮力、成长&#xff0c;横冲直撞&#xf…...

wordpress文章关联/网盘搜索神器

4个类就可体验HADOOP-RPC的简单、实用。 一&#xff0c;writable-rpc 一&#xff0c;协议 所谓协议&#xff0c;实际是一个接口&#xff0c;用来定义该RPC提供的功能 package rpc.writeable;public interface MyProtocol {void mkdir(String path);String getName(String na…...

网站建设公司谁管/网店推广的作用

本来打算用绘制贝塞尔曲线的方法绘制心形&#xff0c;可是本数学渣怎么都搞不定那几个控制点坐标。研究了一上午&#xff0c;通过lineTo方法&#xff0c;最终还是绘制出封闭的心形图。还收获了意外的效果。 看来就差个女朋友&#xff0c;给她看了。 代码如下&#xff1a; .h文件…...

做网站用什么云服务器吗/营销活动有哪些

文章目录简介均值滤波实现Sobel边缘检测实现福利简介 FPGA数字图像处理系列终于迎来了第三更了&#xff0c;马上要开始写毕业论文了&#xff0c;这次的教程写的比较潦草&#xff0c;不过代码和上位机都是完整的&#xff0c;重点参考了《基于FPGA的数字图像处理原理及应用》的第…...