Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从数据库读取BLOB(PDF内容),编辑并输出PDF编辑文件,而不创建物理文件_Java_Jsp_Servlets_Blob_Itext - Fatal编程技术网

Java 从数据库读取BLOB(PDF内容),编辑并输出PDF编辑文件,而不创建物理文件

Java 从数据库读取BLOB(PDF内容),编辑并输出PDF编辑文件,而不创建物理文件,java,jsp,servlets,blob,itext,Java,Jsp,Servlets,Blob,Itext,我正在使用Oracle数据库,并将PDF内容存储在BLOB字段中 我想读取BLOB内容,然后编辑并输出编辑后的内容 我需要做的编辑是: 在BLOB内容上方添加标题 在每一页上加上一个水印 在每页上添加页脚 然后我需要输出文件,而不需要在响应流中创建任何物理文件 我试图用itext实现这一点,但没有达到任何目的。我被卡住了,不知道从哪里开始 有时我可能不得不将blob内容合并成一个,但这是百万分之一的事情…所以现在不必担心了 如何在java中实现上述三个步骤的主要要求?是否可以使用Itext?

我正在使用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内容,但不带标题

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

我得到的文档中有标题内容,没有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();