从数据库中读取BLOB(PDF内容)并编辑和输出PDF编辑的文件,而无需创建物理文件

我正在使用Oracle数据库并将PDF内容存储在BLOB字段中。

我想阅读BLOB内容,然后编辑并输出已编辑的内容。

我需要做的编辑是:

  • 在BLOB内容上方添加标题
  • 在每页上添加水印
  • 在每个页面上添加页脚

然后我需要输出文件,而不会在响应流中创建任何物理文件。

我尝试使用itext实现这一点,但没有到达任何地方。 我被困住了,不知道从哪里开始。

有时候我可能不得不将blob内容组合成一个,但有些事情必然会发生在一百万……所以现在不是一个问题……

如何在java中使用以上三个步骤来实现我的主要要求? Itext可以吗? 或者是否有其他可用的库?

数据库:Oracle 10g第2版

操作系统:Linux Fedora / Redhat

前端: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内容而没有标题。

当我在代码中更改一点(更改最后几行的顺序)时:

 document.close(); servletOutputStream.flush(); servletOutputStream.close(); 

我得到了标题内容的文档,没有BLOB字段的pdf内容。 它关闭的第一件事(servletoutputstream / document)被抛出作为输出。

当我在将输出流中的blob内容放入之前关闭文档时:

 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 > startxref 620 %%EOF 

我需要输出文件和pdf内容以及标题。

希望这个编辑有点帮助……

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  0) { document.newPage(); } pageOfCurrentReaderPDF++; currentPageNumber++; page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF); cb.addTemplate(page, 0, 0); } pageOfCurrentReaderPDF = 0; outputstream.flush(); document.close(); outputstream.close(); } 

这给了我一个响应文件,它有一个来自DB的BLOB,标题在顶部,并且没有生成任何物理文件。

现在要生成水印,我需要将文档传递给PDfreader,如何在关闭文档之前实现它(即执行document.close() ,这会在文件流关闭时将文件放入水印标记)

我在这段代码中做错了什么? 如何使用水印实现相同的文件,如果没有在后台创建文件也是如此。

您可以尝试以下方法,而不是直接写入servletOutputStream:

  1. 创建ByteArrayOutputStream的实例
  2. 创建“合并”PDF文档的实例。 即PDF格式Blob +具有标题的PDF。 此示例可能有所帮助: http : //java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html
  3. 将合并的PDF写入ByteArrayOutputStream的实例
  4. 设置响应的内容长度
  5. 设置内容类型和内容处置
  6. 从ByteArrayOutputStream获取字节并将这些字节写入servletOutputStream
  7. 关闭ByteArrayOutputStream

如果您不想创建临时文件,那么您只需要将PDF作为InputStream从DB中读取,并让iText从中读取并最终写入响应的OutputStream 。 你的问题实际上太广泛了,无法给出一个非常合适的答案(“我没有得到任何地方”并没有给予很多帮助),所以这里有一个广泛的答案:

 InputStream input = resultSet.getBinaryStream("columnname"); PdfReader reader = new PdfReader(input); // ... OutputStream output = response.getOutputStream(); PdfWriter pdfWriter = PdfWriter.getInstance(document, output); // ... 

您也可以传递ByteArrayOutputStream


根据您的问题更新

  1. 将响应主体传递给PdfWriter 之前,需要设置响应头。

     response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment; filename=output.pdf"); PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream()); // ... 
  2. 摆脱以下几行。 他们只会搞乱事情。

     byte[] bytes = blob.getBytes(1, (int) blob.length()); servletOutputStream.write(bytes, 0, bytes.length); servletOutputStream.flush(); servletOutputStream.close(); 

    PdfWriter已经写入响应正文。 你不需要自己重复。