如何使用Spring JdbcTemplate从Azure SQL读取BLOB并修改内容后存储为PDF
基于Spring JdbcTemplate处理Azure SQL中PDF BLOB的可修改操作流程
核心逻辑
网上常见的示例之所以不适用,是因为实现了「数据库BLOB流 -> FileOutputStream」的直连通道,没有预留中间内容修改的环节。你只需要把这个直连链路拆解,在中间插入内存级的内容处理步骤即可,全程不需要依赖磁盘临时文件。
1. 读取数据库varbinary列的BLOB到内存可操作载体
不要直接将ResultSet获取的二进制流对接文件输出流,优先把BLOB内容加载为内存中可读写的结构:
// 通过JdbcTemplate读取目标PDF的BLOB字节 byte[] originalPdfByteArray = jdbcTemplate.queryForObject( "SELECT pdf_blob FROM pdf_record WHERE id = ?", (rs, rowNum) -> rs.getBytes("pdf_blob"), targetRecordId ); // 转为输入流供后续PDF解析使用 ByteArrayInputStream pdfInputSource = new ByteArrayInputStream(originalPdfByteArray);
如果PDF体积较大(超过内存可承载阈值),可以将上述读取方式替换为
rs.getBinaryStream()做分页流式读取,避免一次性加载全量字节导致OOM。
2. 在内存中完成PDF内容修改
借助专业PDF处理库(如OpenPDF、合规版本的iText)对内存流中的PDF做解析、修改,全程在内存缓冲区完成操作,不生成磁盘临时文件:
// 示例内存修改逻辑 PdfReader pdfReader = new PdfReader(pdfInputSource); ByteArrayOutputStream modifiedPdfBuffer = new ByteArrayOutputStream(); PdfStamper stamper = new PdfStamper(pdfReader, modifiedPdfBuffer); // 在此处替换为你的自定义修改逻辑:如替换指定位置文本、添加电子签章、补充页眉页脚等 int pageCount = pdfReader.getNumberOfPages(); for (int pageIndex = 1; pageIndex <= pageCount; pageIndex++) { PdfContentByte pageContent = stamper.getOverContent(pageIndex); pageContent.beginText(); pageContent.setFontAndSize(BaseFont.createFont(), 10); pageContent.showTextAligned( Element.ALIGN_RIGHT, "内容已校验", pdfReader.getPageSize(pageIndex).getWidth() - 36, 36, 0 ); pageContent.endText(); } stamper.close(); pdfReader.close(); // 拿到修改完成的最终PDF字节数组 byte[] finalPdfContent = modifiedPdfBuffer.toByteArray();
3. 处理完成后的输出/回写
修改逻辑执行完成后,可根据需求选择两种处理方向:
- 回写Azure SQL数据库:直接将修改后的字节数组通过JdbcTemplate更新到对应varbinary列,无需经过文件落地
jdbcTemplate.update( "UPDATE pdf_record SET pdf_blob = ?, update_time = GETDATE() WHERE id = ?", finalPdfContent, targetRecordId ); - 导出为本地PDF文件:此时再对接FileOutputStream完成文件写入即可,和常规示例的落盘逻辑一致
try (FileOutputStream fileOut = new FileOutputStream("modified_result.pdf")) { fileOut.write(finalPdfContent); }
关键注意点
- 不要手动直接修改PDF的原始字节数据,PDF有固定的二进制结构,手动篡改极易造成文件损坏无法打开
- 全流程尽量用内存流处理,避免生成不必要的磁盘临时文件,减少IO开销和临时文件泄露的风险
- 大体积PDF处理时要注意内存占用阈值,结合流式解析能力调整代码实现,避免内存溢出
内容的提问来源于stack exchange,提问作者Manoj kumar
相关产品推荐
相关产品推荐

