如何用Python结合MySQL填充指定位置的非空白PDF表单?
可行技术方案:MySQL数据填充至带多行多列记录的PDF表单
完全可以实现,核心是根据PDF的类型(可编辑表单/静态文档)选择对应工具,结合MySQL数据查询完成精准填充。以下是几种成熟的方案:
1. Python 方案(灵活易上手)
Python生态里有多个库能处理PDF填充,分两种场景:
场景A:PDF是带预定义表单域的AcroForm
如果你的PDF表单已经为每行每列的历史记录定义了命名域(比如record_1_col1、record_1_col2、record_2_col1),用PyPDF2就能快速填充:
import PyPDF2 import pymysql # 1. 从MySQL查询数据 conn = pymysql.connect(host='localhost', user='user', password='pass', db='your_db') cursor = conn.cursor() cursor.execute("SELECT col1, col2, col3 FROM history LIMIT 10") records = cursor.fetchall() conn.close() # 2. 加载PDF表单并填充 pdf_reader = PyPDF2.PdfReader("template.pdf") pdf_writer = PyPDF2.PdfWriter() for page in pdf_reader.pages: # 获取表单域 fields = page.get_fields() # 循环填充每行记录 for idx, (col1, col2, col3) in enumerate(records, start=1): fields[f"record_{idx}_col1"].update({"/V": col1}) fields[f"record_{idx}_col2"].update({"/V": col2}) fields[f"record_{idx}_col3"].update({"/V": col3}) pdf_writer.add_page(page) # 保存填充后的PDF with open("filled_form.pdf", "wb") as f: pdf_writer.write(f)
场景B:静态PDF(无表单域,需精准坐标填充)
如果PDF是静态文档,需要指定坐标写入文本,用PyMuPDF(fitz)更灵活,支持精准定位:
import fitz import pymysql # 1. 查询MySQL数据 conn = pymysql.connect(host='localhost', user='user', password='pass', db='your_db') cursor = conn.cursor() cursor.execute("SELECT col1, col2, col3 FROM history LIMIT 10") records = cursor.fetchall() conn.close() # 2. 打开PDF并写入数据 doc = fitz.open("template.pdf") page = doc[0] # 假设记录在第一页 # 定义起始坐标和行高,根据实际PDF调整 start_x, start_y = 50, 200 row_height = 20 for idx, (col1, col2, col3) in enumerate(records): # 计算当前行的Y坐标 current_y = start_y + idx * row_height # 写入每列数据,X坐标根据实际列位置调整 page.insert_text((start_x, current_y), str(col1), fontsize=10) page.insert_text((start_x + 100, current_y), str(col2), fontsize=10) page.insert_text((start_x + 200, current_y), str(col3), fontsize=10) doc.save("filled_form.pdf") doc.close()
2. Java 方案(企业级场景常用)
用iText 7(Java处理PDF的主流库),支持AcroForm填充和动态表格插入,适合复杂的多行多列场景:
- 先通过JDBC连接MySQL查询数据,整理成List或实体类集合;
- 若为AcroForm,直接通过
PdfAcroForm获取域并赋值; - 若需动态添加行,可创建
Table对象,将数据填入后插入到PDF指定位置。
核心代码片段:
// 连接MySQL查询数据(省略JDBC代码) List<HistoryRecord> records = queryHistoryRecords(); // 加载PDF模板 PdfDocument pdfDoc = new PdfDocument(new PdfReader("template.pdf"), new PdfWriter("filled_form.pdf")); PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true); // 填充表单域 for (int i = 0; i < records.size(); i++) { HistoryRecord record = records.get(i); form.getField("record_" + (i+1) + "_col1").setValue(record.getCol1()); form.getField("record_" + (i+1) + "_col2").setValue(record.getCol2()); } pdfDoc.close();
3. PHP 方案(Web场景适配)
适合Web项目中生成PDF,用FPDI + FPDF组合,支持加载现有PDF并精准写入内容:
// 连接MySQL查询数据 $conn = mysqli_connect("localhost", "user", "pass", "your_db"); $result = mysqli_query($conn, "SELECT col1, col2, col3 FROM history LIMIT 10"); $records = mysqli_fetch_all($result, MYSQLI_ASSOC); mysqli_close($conn); // 初始化FPDI require_once('fpdf.php'); require_once('fpdi.php'); $pdf = new FPDI(); $pdf->AddPage(); // 加载PDF模板 $pageCount = $pdf->setSourceFile("template.pdf"); $tplIdx = $pdf->importPage(1); $pdf->useTemplate($tplIdx); // 设置字体和起始坐标 $pdf->SetFont('Arial', '', 10); $startX = 50; $startY = 200; $rowHeight = 20; // 循环写入数据 foreach ($records as $idx => $record) { $currentY = $startY + $idx * $rowHeight; $pdf->SetXY($startX, $currentY); $pdf->Write(0, $record['col1']); $pdf->SetXY($startX + 100, $currentY); $pdf->Write(0, $record['col2']); $pdf->SetXY($startX + 200, $currentY); $pdf->Write(0, $record['col3']); } $pdf->Output('filled_form.pdf', 'F');
4. 命令行工具方案(轻量自动化)
用pdftk(PDF Toolkit)配合Shell脚本,适合简单的表单域填充:
- 先把MySQL数据导出为键值对格式的FDF文件(比如
record_1_col1=value1); - 用pdftk填充PDF:
# 导出MySQL数据为FDF格式(示例) mysql -u user -ppass your_db -e "SELECT CONCAT('record_', idx, '_col1=', col1, '\nrecord_', idx, '_col2=', col2) FROM (SELECT @row:=@row+1 AS idx, col1, col2 FROM history, (SELECT @row:=0) r) t" > data.fdf # 填充PDF pdftk template.pdf fill_form data.fdf output filled_form.pdf
关键注意事项
- 优先确认PDF类型:如果是可编辑的AcroForm,填充表单域的方式更精准,避免坐标偏移;
- 动态多行记录:若表单未预留固定行,需用支持动态内容插入的库(如iText、PyMuPDF)生成表格并插入;
- 坐标校准:若用坐标写入,需要先查看PDF的坐标系统(多数PDF以左下角为原点),可以用PDF编辑器(如Adobe Acrobat)获取元素坐标。
内容的提问来源于stack exchange,提问作者user20176030
相关产品推荐
相关产品推荐

