Java 从数据库读取BLOB(PDF内容),编辑并输出PDF编辑文件,而不创建物理文件
我正在使用Oracle数据库,并将PDF内容存储在BLOB字段中 我想读取BLOB内容,然后编辑并输出编辑后的内容 我需要做的编辑是:Java 从数据库读取BLOB(PDF内容),编辑并输出PDF编辑文件,而不创建物理文件,java,jsp,servlets,blob,itext,Java,Jsp,Servlets,Blob,Itext,我正在使用Oracle数据库,并将PDF内容存储在BLOB字段中 我想读取BLOB内容,然后编辑并输出编辑后的内容 我需要做的编辑是: 在BLOB内容上方添加标题 在每一页上加上一个水印 在每页上添加页脚 然后我需要输出文件,而不需要在响应流中创建任何物理文件 我试图用itext实现这一点,但没有达到任何目的。我被卡住了,不知道从哪里开始 有时我可能不得不将blob内容合并成一个,但这是百万分之一的事情…所以现在不必担心了 如何在java中实现上述三个步骤的主要要求?是否可以使用Itext?
- 在BLOB内容上方添加标题
- 在每一页上加上一个水印
- 在每页上添加页脚
oracle.sql.BLOB blob = (BLOB) rs.getBlob("MYPDF");
byte[] bytes = blob.getBytes(1, (int) blob.length());
InputStream is = blob.getBinaryStream();
Document document=new Document();
ServletOutputStream servletOutputStream = response.getOutputStream();
PdfWriter writer=PdfWriter.getInstance(document, servletOutputStream);
document.open();
document.add(new Paragraph("Some title"));
document.add(new Paragraph("Some title"));
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();
document.close();
程序在数据库的BLOB字段中输出pdf内容,但不带标题
当我将代码中的一点(更改最后几行的顺序)更改为:
我得到的文档中有标题内容,没有BLOB字段的pdf内容。
它关闭的第一件事(servletoutputstream/document)作为输出抛出
当我在将blob内容放入outputstream之前关闭文档时:
document.close();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();
我看到浏览器显示如下内容:
%PDF-1.4 %���� 2 0 obj <>stream x�+�r �26S�00SI�2P�5��1���BҸ4��sSJ2KrR5C��*P�B�5�+��k)&� endstream endobj 4 0 obj <<<>>>/MediaBox[0 0 595 842]>> endobj 1 0 obj <> endobj 3 0 obj <> endobj 5 0 obj <> endobj 6 0 obj <> endobj xref 0 7 0000000000 65535 f 0000000304 00000 n 0000000015 00000 n 0000000392 00000 n 0000000147 00000 n 0000000443 00000 n 0000000488 00000 n trailer <]/Info 6 0 R/Size 7>> startxref 620 %%EOF
%PDF-1.4%���� 2 0 obj流x�+�R�26秒�00SI�2P�5.��1.���BҸ4��sSJ2KrR5C��*P�B�5.�+��(k)&� endstream endobj 4 0 obj/MediaBox[0 0 595 842]>>endobj 1 0 obj endobj 3 0 obj endobj 5 0 obj endobj 6 0 obj endobj外部参照0 7 000000 65535 f 0000000 304 00000 n 00000000 15 00000 n 0000000 3920 00000 n 0000000 147 0000000 0000000 4430 0000000 n 0000000 488 00000n拖车>开始外部参照620%%EOF
我需要与pdf内容和标题以及输出文件
希望这个编辑有点帮助
更新(响应标题和BLOB内容而抛出的文件):
Document document = new Document(PageSize.A4, 108, 72, 30, 72);
PdfWriter writer = PdfWriter.getInstance(document, outputstream);
document.open();
///-----Added Some Title----///
rs = stmt.executeQuery(queryToGetBLOBCONTENT);
if (rs.next()) {
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=watermark.pdf");
oracle.sql.BLOB blob = (BLOB) rs.getBlob("MYPDF");
byte[] bytes = blob.getBytes(1, (int) blob.length());
InputStream is = blob.getBinaryStream();
PdfReader pdfReader = new PdfReader(is, bytes);
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
PdfImportedPage page;
int currentPageNumber = 0;
int pageOfCurrentReaderPDF = 0;
while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
if (pageOfCurrentReaderPDF > 0) {
document.newPage();
}
pageOfCurrentReaderPDF++;
currentPageNumber++;
page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
cb.addTemplate(page, 0, 0);
}
pageOfCurrentReaderPDF = 0;
outputstream.flush();
document.close();
outputstream.close();
}
Document Document=新文档(PageSize.a4108,72,30,72);
PdfWriter writer=PdfWriter.getInstance(文档,outputstream);
document.open();
///-----增加了一些标题----///
rs=stmt.executeQuery(queryToGetBLOBCONTENT);
如果(rs.next()){
response.setContentType(“application/pdf”);
setHeader(“内容处置”、“附件;文件名=watermark.pdf”);
oracle.sql.BLOB BLOB=(BLOB)rs.getBlob(“MYPDF”);
byte[]bytes=blob.getBytes(1,(int)blob.length();
InputStream为=blob.getBinaryStream();
PdfReader PdfReader=新的PdfReader(is,字节);
BaseFont bf=BaseFont.createFont(BaseFont.HELVETICA、BaseFont.CP1252、BaseFont.NOT_EMBEDDED);
PdfContentByte cb=writer.getDirectContent();//保存PDF文件
PDF导入页面;
int currentPageNumber=0;
int pageOfCurrentReaderPDF=0;
而(pageOfCurrentReaderPDF0页){
document.newPage();
}
pageOfCurrentReaderPDF++;
currentPageNumber++;
page=writer.getImportedPage(pdfReader,pageOfCurrentReaderPDF);
cb.addTemplate(第0页,第0页);
}
pageOfCurrentReaderPDF=0;
outputstream.flush();
document.close();
outputstream.close();
}
这给了我一个文件作为响应,其中包含一个来自DB的BLOB,标题在顶部,并且在没有生成任何物理文件的情况下完成
现在要生成水印,我需要将文档传递给PDfreader,在关闭文档之前如何实现这一点(即,执行document.close()
,当流关闭时,它将输出不带水印的文件)
我在这个代码中做错了什么?如果不想创建临时文件,则只需从数据库中获取PDF作为
输入流
,然后让iText读取,最后写入响应的输出流
。你的问题实际上太宽泛了,无法给出一个合适的答案(“我一事无成”没有给出太多的答案),所以这里有一个宽泛的答案:
InputStream input = resultSet.getBinaryStream("columnname");
PdfReader reader = new PdfReader(input);
// ...
OutputStream output = response.getOutputStream();
PdfWriter pdfWriter = PdfWriter.getInstance(document, output);
// ...
您也可以改为通过tearrayoutputstream传递
根据您的问题更新:
在将响应正文传递到PdfWriter
之前,需要设置响应头
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
// ...
去掉下面几行。他们只会把事情搞砸
byte[] bytes = blob.getBytes(1, (int) blob.length());
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();
PdfWriter
将已经写入响应主体。你不需要自己重复
您可以尝试以下方法,而不是直接写入servletOutputStream:
创建ByteArrayOutputStream的实例
创建“合并”PDF文档的实例。也就是说,PDF表单Blob+有标题的PDF。此示例可能有助于:
将合并的PDF写入ByteArrayOutputStream的实例
设置响应的内容长度
设置内容类型和内容处置
从ByteArrayOutputStream获取字节,并将这些字节写入servletOutputStream
靠近TearrayOutstream
我已经添加了几行我尝试过的代码,希望它有帮助,并使问题变得不那么宽泛…我没有添加代码,因为它只在任何一个方向上工作(即,无论是DB中的BLOB内容还是使用iText的标题),我没有任何要合并的物理文件,我唯一拥有的是一个Blob内容和作为标题放入的数据,而不是文件…标题是从某些用户输入和DB字段动态生成的…请参阅我发布的代码…P
byte[] bytes = blob.getBytes(1, (int) blob.length());
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();