如何将表格型PDF转换为Excel以保留空列结构?
如何还原PDF表格结构并转换为Excel(保留空列)
你的问题根源在于纯文本提取无法保留表格的列位置信息——原PDF表格的空列仅靠空白字符占位,提取后会被合并压缩,导致CSV/Excel无法识别空列。要解决这个问题,必须先识别PDF中的表格结构,再按行列映射写入Excel。
以下是两种可行的Java实现方案:
方案1:使用iText 7 + Apache POI
iText 7提供了专门的表格提取API,能精准识别PDF中的结构化表格,结合Apache POI可直接将数据写入Excel并保留空列。
步骤1:添加Maven依赖
<dependencies> <!-- iText 7 核心及表格提取组件 --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.2.5</version> <type>pom</type> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-table-extractor</artifactId> <version>7.2.5</version> </dependency> <!-- Apache POI 用于生成Excel文件 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.5</version> </dependency> </dependencies>
步骤2:代码实现
import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.layout.element.Table; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; public class PdfTableToExcel { public static void convertPdfTableToExcel(String pdfPath, String excelPath) throws IOException { try (PdfReader reader = new PdfReader(pdfPath); PdfDocument pdfDoc = new PdfDocument(reader); Workbook workbook = new XSSFWorkbook(); FileOutputStream fos = new FileOutputStream(excelPath)) { Sheet sheet = workbook.createSheet("PDF表格"); int rowIdx = 0; // 遍历PDF每一页提取表格 for (int pageNum = 1; pageNum <= pdfDoc.getNumberOfPages(); pageNum++) { List<Table> tables = Table.extractTables(pdfDoc.getPage(pageNum)); for (Table table : tables) { // 遍历表格行,写入Excel table.getRows().forEach(tableRow -> { Row excelRow = sheet.createRow(rowIdx++); int colIdx = 0; // 遍历所有单元格(包括空列) tableRow.getCells().forEach(cell -> { String cellText = cell.getText().trim(); excelRow.createCell(colIdx++).setCellValue(cellText); }); }); } } // 自动调整列宽 for (int i = 0; i < sheet.getRow(0).getPhysicalNumberOfCells(); i++) { sheet.autoSizeColumn(i); } workbook.write(fos); } } public static void main(String[] args) throws IOException { convertPdfTableToExcel("example.pdf", "student.xlsx"); } }
方案2:使用Apache PDFBox + Apache POI
Apache PDFBox的表格扩展工具可识别文本表格,适合处理纯文本模拟的PDF表格(无结构化表格标签)。
步骤1:添加Maven依赖
<dependencies> <!-- Apache PDFBox 核心 --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.32</version> </dependency> <!-- PDFBox 表格提取扩展 --> <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox-table-extractor</artifactId> <version>2.0.32</version> </dependency> <!-- Apache POI --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.5</version> </dependency> </dependencies>
步骤2:代码实现
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class PdfBoxTableToExcel { public static void convert(String pdfPath, String excelPath) throws IOException { try (PDDocument document = PDDocument.load(new java.io.File(pdfPath)); Workbook workbook = new XSSFWorkbook(); FileOutputStream fos = new FileOutputStream(excelPath)) { Sheet sheet = workbook.createSheet("PDF表格"); int rowIndex = 0; List<List<String>> tableData = new ArrayList<>(); // 遍历每一页提取文本,按多空格拆分列(保留空项) PDFTextStripper stripper = new PDFTextStripper(); for (int page = 0; page < document.getNumberOfPages(); page++) { stripper.setStartPage(page + 1); stripper.setEndPage(page + 1); String pageText = stripper.getText(document); String[] lines = pageText.split("\n"); for (String line : lines) { // 按2个及以上空格拆分,-1参数保留末尾空列 String[] columns = line.split("\\s{2,}", -1); tableData.add(List.of(columns)); } } // 将数据写入Excel for (List<String> rowData : tableData) { Row row = sheet.createRow(rowIndex++); int colIndex = 0; for (String cell : rowData) { row.createCell(colIndex++).setCellValue(cell.trim()); } } workbook.write(fos); } } public static void main(String[] args) throws IOException { convert("example.pdf", "student.xlsx"); } }
关键说明
- 优先选择iText方案:对带结构化标签的PDF表格识别精度更高,能完美保留空列。
- 纯文本模拟的表格:需通过文本的X坐标或固定宽度判断列边界,PDFBox方案可根据实际调整拆分规则。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

