您有大量PDF报告、银行对账单或监管申报,里面的表格数据需要进入数据库、电子表格或分析流水线。从PDF查看器中将表格复制粘贴到Excel中,到第三页就会破坏行和列结构。Total PDF Converter X可通过命令行批量从PDF文件提取表格到CSV,无需GUI。将其安装在Windows服务器上,通过脚本或ActiveX调用,即可实现无人值守运行。
*.pdf),转换器即可在一次运行中处理所有匹配文件-CSVDelimiter使用逗号、分号、制表符或竖线,以匹配目标系统-Encoding使用UTF-8、UTF-16或ANSI,干净地处理非拉丁字符-CSVQuotation包裹文本字段,保护单元格值内的逗号
Windows 7/8/10/11 • Server 2008/2012/2016/2019/2022
PDF是为视觉分发和打印而设计的固定布局格式。PDF中的表格不是结构化数据对象 — 它是定位在页面上特定x/y坐标处的一系列文本片段。查看器将它们渲染成看起来像表格的样子,但文件本身没有行、列或单元格。这就是为什么从PDF手工复制粘贴很少能产生干净的表格输出。
CSV是一种纯文本数据格式,每行一条记录,字段由分隔符分隔。它直接导入Excel、Google Sheets、SQL数据库、pandas DataFrame、R、Power BI、Tableau以及现存的每个ETL工具。当PDF中绑定的数据需要进入分析或会计工作流时,必须先转换为CSV。
| CSV | ||
|---|---|---|
| 用途 | 视觉分发、打印、归档 | 数据摄取和分析 |
| 结构 | 页面坐标,无真正的表格 | 行和列,原生 |
| 编辑 | 困难,需要PDF编辑器 | 在任何文本编辑器或电子表格中打开 |
| 手工复制粘贴 | 丢失表格结构 | 完整保留结构 |
| 工作流 | 流水线末端文档 | 数据流水线的起点 |
注意:自动PDF到CSV提取在基于文本的PDF上工作 — 由会计系统、报表引擎或电子表格/数据库另存为PDF生成的PDF。扫描PDF(纸张图像)不包含文本层,需要OCR作为单独的预处理步骤,然后才能进行CSV提取。
从上方链接下载安装程序,在Windows服务器或工作站上运行。安装不到一分钟即可完成。转换器直接解析PDF的文本层 — 无需外部PDF阅读器、Acrobat或Office安装。
打开cmd.exe或PowerShell。转换器可执行文件为PDFConverter.exe,位于安装文件夹中(通常为C:\Program Files\CoolUtils\TotalPDFConverterX\)。将其添加到系统PATH,或在命令中使用完整路径。
最简单的命令是从文件夹中所有PDF文件提取表格到CSV:
PDFConverter.exe C:\Reports\*.pdf C:\Output\ -c CSV
此命令处理C:\Reports\中的每个.pdf文件,并将生成的CSV文件保存到C:\Output\。每个PDF生成一个同名的CSV。多页PDF默认连接为每个源文件一个CSV。
使用附加标志控制CSV格式:
PDFConverter.exe C:\Reports\*.pdf C:\Output\ -c CSV -CSVDelimiter ; -CSVQuotation " -Encoding UTF-8 -log C:\Logs\pdf2csv.log
-CSVDelimiter ; — 字段分隔符(逗号、分号、制表符、竖线)-CSVQuotation " — 用双引号包裹文本字段,保护单元格内的逗号-Encoding UTF-8 — 输出编码(UTF-8、UTF-16、ANSI),用于正确处理非拉丁字符-log C:\Logs\pdf2csv.log — 写入转换日志以便验证将命令保存到.bat文件中,并通过Windows任务计划程序安排执行:
@echo off "C:\Program Files\CoolUtils\TotalPDFConverterX\PDFConverter.exe" C:\Incoming\*.pdf C:\Archive\CSV\ -c CSV -CSVDelimiter ; -Encoding UTF-8 -log C:\Logs\pdf2csv.log
此脚本每晚(或按您设定的任何间隔)运行提取,并写入日志文件以便您验证结果。将其与将CSV文件导入数据库或分析仓库的后续步骤配对。
Total PDF Converter X包含完整的ActiveX接口。您可以从任何兼容COM的环境调用转换器 — .NET、VBScript、PHP、Python、Ruby或ASP。这使您能够将PDF到CSV的提取嵌入自己的Web应用、内部网门户或文档工作流,无需通过命令行进程调用。
示例(C#/.NET):
PDFConverterX Cnv = new PDFConverterX();
Cnv.Convert("C:\\Reports\\statement.pdf", "C:\\Output\\statement.csv", "-c CSV -CSVDelimiter ; -Encoding UTF-8 -log c:\\Logs\\pdf.log");
示例(PHP):
$c = new COM("PDFConverter.PDFConverterX");
$c->convert("C:\\Reports\\statement.pdf", "C:\\Output\\statement.csv", "-c CSV -CSVDelimiter ; -Encoding UTF-8 -log c:\\Logs\\pdf.log");
同样的调用方式适用于ASP.NET、VBScript、Python、Ruby、Perl和JavaScript(Windows Script Host)。您的Web应用可以接受上传的PDF文件,并实时向用户返回可直接导入的CSV数据。
| 功能 | 在线转换器 | Total PDF Converter X |
|---|---|---|
| 批量处理 | 一次一个文件 | 每批次无限文件 |
| 文件隐私 | 文件上传至第三方服务器 | 文件不会离开您的机器 |
| 机密数据 | 风险 — 银行对账单、薪资、申报 | 安全 — 本地处理 |
| 文件大小限制 | 典型5–25 MB上限 | 无限制 |
| 分隔符控制 | 固定逗号,无选择 | 逗号、分号、制表符、竖线 |
| 编码控制 | 常常仅ANSI,破坏Unicode | 可选UTF-8、UTF-16、ANSI |
| 自动化 | 仅手动操作 | 命令行、.bat、任务计划程序、ActiveX |
| 服务器部署 | 不可能 | 专为服务器设计,无需GUI |
| 需要互联网 | 是 | 否 |
转换器解析PDF的文本层,并基于坐标和对齐重建行和列结构。多列报告布局、合并的标题以及跨多页的表格都在一次运行中处理 — 而不是作为一串断开的单词。
Total PDF Converter X专为无人值守使用而设计。没有GUI窗口,没有对话框,没有确认提示,没有Acrobat依赖。它从命令行静默运行,或作为服务的一部分运行 — 正是生产提取流水线所需要的。
带德语变音符号的银行对账单、波兰语变音符号、西里尔字母商家名或中文交易对手在CSV输出中保持可读。在命令行上使用-Encoding UTF-8,生成的文件可干净地导入任何现代数据库或BI工具。
同一命令行工具可将PDF转换为DOC、XLS、HTML、TXT、TIFF、JPEG等格式。一次安装即可覆盖您可能需要的每个PDF转换目标。将-c CSV改为-c XLS,即可获得具有相同批处理和自动化功能的Excel工作簿。
Windows 7/8/10/11 • Server 2008/2012/2016/2019/2022
"季度财报以PDF形式到达,我们在Excel中建模。Total PDF Converter X从命令行运行,遍历整个10-Q申报文件夹,在不到一分钟内生成干净的CSV。多列表格和合并的标题正确结构化输出,这是我们尝试的两个先前工具的致命缺陷。分号分隔符和UTF-8标志意味着欧洲发行人不再破坏我们的导入。"
Caroline Whitfield Senior Financial Analyst, Mid-Market Equity Research
"我们每天摄取数百份银行对账单进行调节。围绕PDFConverter.exe的.bat脚本包装器将CSV文件放入热文件夹,我们的ETL流水线拾取它们。服务器上零GUI占用,无Acrobat授权,日志文件为审计提供了书面记录。设置花了大约一个小时,包括从我们内部C#工具进行ActiveX测试。"
Rohan Mehta Data Engineer, Banking Operations
"现场约定经常给我们PDF总账(来自客户系统)。将其转换为CSV过去意味着繁琐的复制粘贴或购买IDEA导入。现在我们在U盘安装的副本上运行转换器,将CSV直接加载到我们的分析工作底稿中。扫描PDF仍需要上游OCR,但对于原生PDF,表格检测可靠。文档可以更全面,但技术支持在一天内回复。"
Anika Larsen Audit Specialist, Big Four Practice
PDFConverter.exe C:\Reports\*.pdf C:\Output\ -c CSV。此命令从源文件夹中的每个PDF提取表格,并将其作为CSV文件写入。添加-CSVDelimiter ;、-Encoding UTF-8或-log等标志以控制输出。-CSVDelimiter后跟字符。-CSVDelimiter ;用于分号(在欧洲区域常见,逗号是小数分隔符),-CSVDelimiter \t用于制表符,或-CSVDelimiter |用于竖线。默认为逗号。-Encoding UTF-8。这会生成UTF-8编码的CSV文件,保留PDF中存在的德语变音符号、波兰语变音符号、西里尔字母、中文、日文以及任何其他Unicode字符。也支持UTF-16和ANSI。-CSVQuotation "用双引号包裹文本字段。转换器按RFC 4180转义嵌入的引号,因此"Smith, John"这样的值可以往返进入Excel、pandas或任何标准CSV解析器,而不会破坏列计数。PDFConverter.PDFConverterX)。您可以从.NET、PHP、Python、VBScript、ASP、Ruby、Perl及任何其他兼容COM的环境中调用它,将PDF到CSV的提取直接嵌入您的应用程序。
string src = @"C:\test\Source.pdf";
string dest = @"C:\test\Dest.docx";
var cnv = new PDFConverterX();
cnv.Convert(src, dest, "-cDOC -log c:\\test\\PDF.log");
if (!string.IsNullOrEmpty(cnv.ErrorMessage))
throw new Exception(cnv.ErrorMessage);
public static class Function1
{
[FunctionName("Function1")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
StringBuilder sbLogs = new StringBuilder();
sbLogs.AppendLine("started...");
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
var assemblyDirectoryPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
assemblyDirectoryPath = assemblyDirectoryPath.Substring(0, assemblyDirectoryPath.Length - 4);
var executablePath = $@"{assemblyDirectoryPath}\Converter\PDFConverterX.exe";
sbLogs.AppendLine(executablePath + "...");
var srcPath = $@"{assemblyDirectoryPath}\src\sample.pdf";
var outPath = Path.GetTempFileName() + ".docx";
startInfo.FileName = executablePath;
if (File.Exists(outPath))
{
File.Delete(outPath);
}
if (File.Exists(executablePath) && File.Exists(srcPath))
{
sbLogs.AppendLine("files exists...");
}
else
sbLogs.AppendLine("EXE & source files NOT exists...");
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = $"\"{srcPath}\" \"{outPath}\" -cDOC";
using (Process exeProcess = Process.Start(startInfo))
{
sbLogs.AppendLine($"wait...{DateTime.Now.ToString()}");
exeProcess.WaitForExit();
sbLogs.AppendLine($"complete...{DateTime.Now.ToString()}");
}
sbLogs.AppendLine("Conversion complete.");
}
catch (Exception ex)
{
sbLogs.AppendLine(ex.ToString());
}
return new OkObjectResult(sbLogs);
}
}
dim C
Set C=CreateObject("PDFConverter.PDFConverterX")
C.Convert "c:\test\source.pdf", "c:\test\dest.docx", "-cDOC -log c:\test\PDF.log"
Response.Write C.ErrorMessage
set C = nothing
dim C
Set C=CreateObject("PDFConverter.PDFConverterX")
Response.Clear
Response.AddHeader "Content-Type", "binary/octet-stream"
Response.AddHeader "Content-Disposition", "attachment; filename=test.docx"
Response.BinaryWrite C.ConvertToStream("C:\www\ASP\Source.pdf", "C:\www\ASP", "-cDOC -log c:\html.log")
set C = nothing
$src="C:\\test\\test.pdf";
$dest="C:\\test\\test.docx";
if (file_exists($dest)) unlink($dest);
$c= new COM("PDFConverter.PDFConverterX");
$c->convert($src,$dest, "-cDOC -log c:\\test\\PDF.log");
if (file_exists($dest)) echo "OK"; else echo "fail:".$c->ErrorMessage;
require 'win32ole'
c = WIN32OLE.new('PDFConverter.PDFConverterX')
src = "C:\\test\\test.pdf"
dest = "C:\\test\\test.docx"
c.convert(src, dest, "-cDOC -log c:\\test\\PDF.log")
if not File.exist?(dest)
puts c.ErrorMessage
end
import win32com.client
import os.path
c = win32com.client.Dispatch("PDFConverter.PDFConverterX")
src = "C:\\test\\test.pdf"
dest = "C:\\test\\test.docx"
c.convert(src, dest, "-cDOC -log c:\\test\\PDF.log")
if not os.path.exists(dest):
print(c.ErrorMessage)
uses Dialogs, Vcl.OleAuto;
var
c: OleVariant;
begin
c := CreateOleObject('PDFConverter.PDFConverterX');
c.Convert('c:\test\source.pdf', 'c:\test\dest.docx', '-cDOC -log c:\test\PDF.log');
if c.ErrorMessage <> '' then
ShowMessage(c.ErrorMessage);
end;
var c = new ActiveXObject("PDFConverter.PDFConverterX");
c.Convert("C:\\test\\source.pdf", "C:\\test\\dest.docx", "-cDOC");
if (c.ErrorMessage != "")
alert(c.ErrorMessage)
use Win32::OLE; my $src = "C:\\test\\test.pdf"; my $dest = "C:\\test\\test.docx"; my $c = CreateObject Win32::OLE 'PDFConverter.PDFConverterX'; $c->convert($src, $dest, "-cDOC -log c:\\test\\PDF.log"); print $c->ErrorMessage if -e $dest;