PHP项目中Doc/PDF转CSV后导入MySQL的可行性咨询
如何在PHP项目中将Doc/PDF文件转换为CSV并导入MySQL
嘿,我之前在PHP项目里处理过类似的需求,分享几个经过实践验证的方案给你:
一、先处理PDF转CSV的情况
PDF的情况分两种:可编辑的文本PDF和扫描生成的图片PDF,处理方式完全不一样:
1. 可编辑文本PDF转CSV
最靠谱的方式是借助Poppler工具集里的pdftotext命令行工具(大部分Linux服务器默认没有,需要先安装:Ubuntu用apt install poppler-utils,CentOS用yum install poppler-utils)。
步骤:
- 用PHP调用
pdftotext把PDF转成纯文本文件 - 解析纯文本,按照你的数据规则提取字段,生成符合标准的CSV
示例代码:
// 1. 把PDF转成带排版的纯文本 $pdfPath = '/path/to/your/target.pdf'; $txtPath = '/path/to/temp/output.txt'; // -layout参数保留原文档排版,方便后续按行/按字段解析 exec("pdftotext -layout {$pdfPath} {$txtPath}", $output, $returnVar); if ($returnVar !== 0) { die('PDF转文本失败,请检查工具是否安装或文件路径是否正确'); } // 2. 读取文本并解析成标准CSV $txtContent = file_get_contents($txtPath); $lines = explode(PHP_EOL, $txtContent); $csvPath = '/path/to/final/result.csv'; $csvFile = fopen($csvPath, 'w'); // 这里假设文档每行数据用多个空格分隔,实际要根据你的文档格式调整 foreach ($lines as $line) { $trimmedLine = trim($line); if (empty($trimmedLine)) continue; // 把多个连续空格替换成单个,再拆分字段 $fields = preg_split('/\s{2,}/', $trimmedLine); // 用fputcsv自动处理逗号、引号等特殊字符的转义,避免CSV格式错误 fputcsv($csvFile, $fields); } fclose($csvFile);
2. 扫描版图片PDF转CSV
这种情况需要先做OCR文字识别,推荐用Tesseract OCR工具(安装方式:Ubuntuapt install tesseract-ocr,CentOSyum install tesseract),结合PHP调用:
// 第一步:把PDF每页转成图片(用Poppler的pdftoppm命令) exec("pdftoppm {$pdfPath} /path/to/temp/pdf_image -png", $output, $returnVar); // 第二步:对生成的第一张图片做OCR(如果是多页PDF,需要循环处理所有图片) exec("tesseract /path/to/temp/pdf_image-1.png /path/to/temp/ocr_result", $output, $returnVar); // 后续步骤和文本PDF一致,读取OCR生成的文本文件,解析转成CSV
二、Doc/Docx转CSV的情况
1. Docx文件(推荐用PHPWord库)
先通过Composer安装PHPWord:composer require phpoffice/phpword
示例代码:
require 'vendor/autoload.php'; $docxPath = '/path/to/your/target.docx'; $csvPath = '/path/to/final/result.csv'; $csvFile = fopen($csvPath, 'w'); $phpWord = \PhpOffice\PhpWord\IOFactory::load($docxPath); $sections = $phpWord->getSections(); foreach ($sections as $section) { $elements = $section->getElements(); foreach ($elements as $element) { if ($element instanceof \PhpOffice\PhpWord\Element\TextRun) { $lineText = ''; // 提取文本块里的所有内容 foreach ($element->getElements() as $textElement) { if ($textElement instanceof \PhpOffice\PhpWord\Element\Text) { $lineText .= $textElement->getText(); } } $trimmedText = trim($lineText); if (!empty($trimmedText)) { // 根据你的文档格式拆分字段,这里假设用空格分隔 $fields = explode(' ', $trimmedText); fputcsv($csvFile, $fields); } } } } fclose($csvFile);
2. 旧版Doc文件
可以用unoconv命令行工具(需要先安装LibreOffice,因为unoconv依赖它),直接把Doc转成CSV:
$docPath = '/path/to/your/target.doc'; $csvPath = '/path/to/final/result.csv'; // -f 指定输出格式为csv,-o 指定输出路径 exec("unoconv -f csv {$docPath} -o {$csvPath}", $output, $returnVar); if ($returnVar !== 0) { die('Doc转CSV失败,请检查LibreOffice和unoconv是否安装'); }
三、将CSV导入MySQL
最高效的方式是用MySQL的LOAD DATA INFILE命令,比PHP循环插入快几个量级:
$dbHost = 'localhost'; $dbUser = 'your_db_user'; $dbPass = 'your_db_password'; $dbName = 'your_db_name'; $csvPath = '/path/to/final/result.csv'; $conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName); if ($conn->connect_error) { die('数据库连接失败: ' . $conn->connect_error); } // 如果CSV文件有表头,用IGNORE 1 LINES跳过第一行 // 注意:如果是远程服务器,可能需要调整MySQL的secure_file_priv参数,或者改用LOAD DATA LOCAL INFILE $sql = "LOAD DATA INFILE '{$csvPath}' INTO TABLE your_target_table FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n' IGNORE 1 LINES;"; if ($conn->query($sql) === TRUE) { echo 'CSV导入数据库成功'; } else { echo '导入失败: ' . $conn->error; } $conn->close();
一些关键注意事项
- 不同文档的格式差异极大,解析时一定要根据你的实际数据结构调整字段拆分逻辑(比如有的文档是制表符分隔,有的是固定宽度)
- 处理中文时要确保PDF/Doc的编码、PHP环境编码、MySQL编码一致(推荐统一用UTF-8)
- 命令行工具的权限问题:要确保PHP进程有执行这些命令的权限,以及读写文件路径的权限
内容的提问来源于stack exchange,提问作者user8579791
相关产品推荐
相关产品推荐

