我正在使用Oracle数据库并将PDF内容存储在BLOB字段中。
我想阅读BLOB内容,然后编辑并输出已编辑的内容。
我需要做的编辑是:
然后我需要输出文件,而不会在响应流中创建任何物理文件。
我尝试使用itext实现这一点,但没有到达任何地方。我被困住了,不知道从哪里开始。
有时我可能不得不将blob内容合并为一个,但有些事情必然会发生在一百万......所以现在不是一个问题......
如何在java中实现上述三个步骤的主要要求? Itext可以吗?或者是否有其他可用的库?
数据库:Oracle 10g第2版
OS: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 <]/Info 6 0 R/Size 7>> 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 < 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();
}
这给了我一个响应文件,它有一个来自DB的BLOB,标题位于顶部,没有生成任何物理文件。
现在要生成水印,我需要将文档传递给PDfreader,如何在关闭文档之前实现该目标(即执行document.close()
,这会将文件没有水印标记为流已关闭)
我在这段代码中做错了什么?如何使用水印创建相同的文件,如果没有在后台创建文件,也是如此。
答案 0 :(得分:2)
如果您不想创建临时文件,那么您只需要从数据库中获取InputStream
的PDF,然后让iText从中读取,最后写入OutputStream
响应。你的问题实际上太广泛了,无法给出一个非常合适的答案(“我没有得到任何地方”并没有给予很多帮助),所以这里有一个广泛的答案:
InputStream input = resultSet.getBinaryStream("columnname");
PdfReader reader = new PdfReader(input);
// ...
OutputStream output = response.getOutputStream();
PdfWriter pdfWriter = PdfWriter.getInstance(document, output);
// ...
您也可以传递ByteArrayOutputStream
。
更新:
您需要在将响应正文传递给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
已经写入响应正文。你不需要自己重复它。
答案 1 :(得分:2)
您可以尝试这种方法,而不是直接写入servletOutputStream: