从数据库中读取BLOB(PDF内容)并编辑和输出PDF编辑的文件,而无需创建物理文件
我正在使用Oracle数据库并将PDF内容存储在BLOB字段中。
I am using an Oracle Database and storing PDF content in a BLOB field.
我想阅读BLOB内容,然后编辑并输出已编辑的内容。
I want to read the BLOB content and then edit and output the edited content.
我需要做的编辑是:
- 在BLOB上方添加一个标题内容
- 在每个页面上添加水印
- 在每页上添加页脚
然后我需要在响应流中没有创建任何物理文件的情况下输出文件。
Then I need to output the file without any physical file getting created that is within the response stream.
我试图用itext实现这个目的但是没有到达任何地方。我被困住了,不知道从哪里开始。
I tried to achieve this using itext but was not reaching anywhere with it. I am stuck and not sure where to start with.
有时候我可能需要将blob内容合并为一个,但有些事情必然会发生在一个百万...现在不用担心...
Also sometimes I might have to combine blob contents into one, buts thats some thing that is bound to happen Once in a million..so that not a concern now...
如何在java中实现上述三个步骤的主要要求? Itext可以吗?或者是否有其他可用的库?
How can I achieve my primary requirements of the above three steps using in java? Is it possible with Itext?? Or is some other library available that would help?
数据库:Oracle 10g第2版
Database : Oracle 10g Release 2
操作系统:Linux Fedora / Redhat
OS: Linux Fedora/Redhat
前端:Java / Servlet / JSP
Front-end: Java/Servlet/JSP
编辑
这是我试图做的事情
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内容而没有标题。
The program outputs the pdf content in BLOB field in the database and without the title.
当我在代码中更改一位(将最后几行的顺序更改为)时:
and when I change a bit in the code (change the order of the last few lines) to:
document.close();
servletOutputStream.flush();
servletOutputStream.close();
我收到包含标题内容的文档,没有BLOB字段的pdf内容。
它关闭的第一件事(servletoutputstream / document)被抛出作为输出。
I get the document with the title content in it and no pdf content of BLOB field. Its the first thing(servletoutputstream/document) that is closed is been thrown as the output.
当我在放入blob内容之前关闭文档outputstream:
And when I closed the document before putting the blob content in 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内容和标题的文件。
I need the file to be outputted with the pdf content and the title as well.
希望这个编辑有所帮助......
Hope this edit helps a little bit...
UPDATE(文件被抛出回复标题和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();
}
这给了我一个响应的文件,它有一个BLOB来自顶部有标题的数据库,并且没有生成任何物理文件。
This gives me a file in response that has a the BLOB from DB with title on the top and that is done without any physical files getting generated.
现在生成水印,我需要将文档传递给PDfreader如何我可以在关闭文档之前实现这一点(即执行 document.close()
,这会在文件流关闭时将文件放在水印上)
Now to generate the water mark and I need to pass the document to the PDfreader how can I achieve that before closing the document (i.e. executing document.close()
, which would out put the file w/o water mark as the stream got closed)
我在这段代码中做错了什么?如何使用水印来实现相同的文件,并且没有在后台创建文件也是如此。
What am I doing wrong in this code? How can I achieve the same file with the watermark and that too without a file getting created at the background.
而不是写作直接到servletOutputStream,您可以尝试这种方法:
Instead of writing directly to servletOutputStream, you can try this approach:
- 创建ByteArrayOutputStream的实例
- 创建实例合并PDF文件。即PDF格式Blob + PDF有标题。此示例可能有所帮助: http:// java- x.blogspot.com/2006/11/merge-pdf-files-with-itext.html
- 将合并的PDF写入ByteArrayOutputStream的实例
- 设置内容响应长度
- 设置内容类型和内容处理
- 从ByteArrayOutputStream获取字节并将这些字节写入servletOutputStream
- 关闭ByteArrayOutputStream
- Create an instance of ByteArrayOutputStream
- Create instance of "merged" PDF document. I.e. PDF form Blob + PDF that has title. This example might help : http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html
- Write the merged PDF to instance of ByteArrayOutputStream
- Set content length of response
- Set content type and content disposition
- Get bytes from ByteArrayOutputStream and write those bytes to servletOutputStream
- Close ByteArrayOutputStream