使用iText和ByteArrayOutputStream向pdf添加水印
pdf以字节[]的形式存储在数据库中。我想在pdf中添加一个水印,并以字节[]的形式将盖章文件存储在数据库中。这是一个Grails应用程序,因此代码在Groovy中。这是:使用iText和ByteArrayOutputStream向pdf添加水印,pdf,grails,groovy,itext,bytearrayoutputstream,Pdf,Grails,Groovy,Itext,Bytearrayoutputstream,pdf以字节[]的形式存储在数据库中。我想在pdf中添加一个水印,并以字节[]的形式将盖章文件存储在数据库中。这是一个Grails应用程序,因此代码在Groovy中。这是: def stampDocument(byte[] orig) { PdfReader pdfReader = new PdfReader(orig) ByteArrayOutputStream baos = new ByteArrayOutputStream() //baos.write(orig,
def stampDocument(byte[] orig) {
PdfReader pdfReader = new PdfReader(orig)
ByteArrayOutputStream baos = new ByteArrayOutputStream()
//baos.write(orig, 0, orig.size())
PdfStamper pdfStamper = new PdfStamper(pdfReader, baos)
com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(new URL("http://localhost:8080/IDSG/assets/stamp.jpg"));
image.setAbsolutePosition(65f, 10f);
image.scalePercent(40f);
int i = 1
while(i <= pdfReader.getNumberOfPages()){
PdfContentByte content = pdfStamper.getUnderContent(i)
content.addImage(image)
i++
}
return baos.toByteArray()
}
def stampDocument(字节[]orig){
PdfReader PdfReader=新PdfReader(原始)
ByteArrayOutputStream bas=新的ByteArrayOutputStream()
//写入(原始,0,原始大小())
PdfStamper PdfStamper=新PdfStamper(pdfReader,BAS)
com.itextpdf.text.Image Image=com.itextpdf.text.Image.getInstance(新URL(“http://localhost:8080/IDSG/assets/stamp.jpg"));
图像。设置绝对位置(65f,10f);
图像缩放率(40f);
int i=1
而(i你忘记了一条重要的线:
pdfStamper.close()
将其插入此行的正前方:
return baos.toByteArray()
关闭母版时,诸如根字典和交叉引用流之类的对象将写入输出流
。没有这些对象,您就没有完整的PDF。您忘记了一条重要的行:
pdfStamper.close()
将其插入此行的正前方:
return baos.toByteArray()
关闭母版时,根词典和交叉引用流等对象将写入输出流
。没有这些对象,您就没有完整的PDF。关闭此错误:
> Caused by AbstractMethodError:
> javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
> ->> 423 | createDocumentBuilderFactory in com.itextpdf.xmp.impl.XMPMetaParser
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 71 | <clinit> in '' | 167 | parseFromBuffer in com.itextpdf.xmp.XMPMetaFactory | 153 | parseFromBuffer in '' |
> 350 | close . . in com.itextpdf.text.pdf.PdfStamperImp | 208 |
> close in com.itextpdf.text.pdf.PdfStamper
>由AbstractMethodError引起:
>javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
>->>423 | com.itextpdf.xmp.impl.XMPMetaParser中的createDocumentBuilderFactory
>在com.itextpdf.xmp.XMPMetaFactory中的parseFromBuffer中的153中的parseFromBuffer中的|
>350 |关闭..在com.itextpdf.text.pdf.PdfStamperImp | 208中|
>在com.itextpdf.text.pdf.PdfStamper中关闭
搜索让我想到了Grails或Java。我使用JDK8和最新的itext jar-5.5.6。Grails有一个旧的itext.jar-2.0.8。它仍然是com.lowagie。更改导入并使用Grails提供的Bouncycastle,而不是Grails服务,而是一个真正的Java类,我终于让它工作得很好
以下是完整的工作代码:
import com.lowagie.text.Image;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.io.IOException;
public class Stamper {
public Stamper(){
}
public byte[] stampDocument(byte[] orig) {
try{
PdfReader pdfReader = new PdfReader(orig);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper pdfStamper = new PdfStamper(pdfReader, baos);
Image image = Image.getInstance(new URL("http://localhost:8080/IDSG/assets/stamp.jpg"));
image.setAbsolutePosition(70f, 10f);
image.scalePercent(40f);
for(int i=1; i<= pdfReader.getNumberOfPages(); i++){
PdfContentByte content = pdfStamper.getUnderContent(i);
content.addImage(image);
}
pdfStamper.close();
return baos.toByteArray();
}
catch (IOException e) {
e.printStackTrace();
return null;
}catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
导入com.lowagie.text.Image;
导入com.lowagie.text.pdf.PdfContentByte;
导入com.lowagie.text.pdf.PdfReader;
导入com.lowagie.text.pdf.PdfStamper;
导入java.io.ByteArrayOutputStream;
导入java.net.URL;
导入java.io.IOException;
公共级压模{
公共母版(){
}
公共字节[]stampDocument(字节[]源){
试一试{
PdfReader PdfReader=新PdfReader(orig);
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
PdfStamper PdfStamper=新PdfStamper(pdfReader,BAS);
Image=Image.getInstance(新URL(“http://localhost:8080/IDSG/assets/stamp.jpg"));
图像。设置绝对位置(70f,10f);
图像缩放率(40f);
对于(int i=1;iClose),此错误:
> Caused by AbstractMethodError:
> javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
> ->> 423 | createDocumentBuilderFactory in com.itextpdf.xmp.impl.XMPMetaParser
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 71 | <clinit> in '' | 167 | parseFromBuffer in com.itextpdf.xmp.XMPMetaFactory | 153 | parseFromBuffer in '' |
> 350 | close . . in com.itextpdf.text.pdf.PdfStamperImp | 208 |
> close in com.itextpdf.text.pdf.PdfStamper
>由AbstractMethodError引起:
>javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
>->>423 | com.itextpdf.xmp.impl.XMPMetaParser中的createDocumentBuilderFactory
>在com.itextpdf.xmp.XMPMetaFactory中的parseFromBuffer中的153中的parseFromBuffer中的|
>350 |关闭..在com.itextpdf.text.pdf.PdfStamperImp | 208中|
>在com.itextpdf.text.pdf.PdfStamper中关闭
搜索让我想到了Grails或Java。我使用JDK8和最新的itext jar-5.5.6。Grails有一个旧的itext.jar-2.0.8。它仍然是com.lowagie。更改导入并使用Grails提供的Bouncycastle,而不是Grails服务,而是一个真正的Java类,我终于让它工作得很好
以下是完整的工作代码:
import com.lowagie.text.Image;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.io.IOException;
public class Stamper {
public Stamper(){
}
public byte[] stampDocument(byte[] orig) {
try{
PdfReader pdfReader = new PdfReader(orig);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper pdfStamper = new PdfStamper(pdfReader, baos);
Image image = Image.getInstance(new URL("http://localhost:8080/IDSG/assets/stamp.jpg"));
image.setAbsolutePosition(70f, 10f);
image.scalePercent(40f);
for(int i=1; i<= pdfReader.getNumberOfPages(); i++){
PdfContentByte content = pdfStamper.getUnderContent(i);
content.addImage(image);
}
pdfStamper.close();
return baos.toByteArray();
}
catch (IOException e) {
e.printStackTrace();
return null;
}catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
导入com.lowagie.text.Image;
导入com.lowagie.text.pdf.PdfContentByte;
导入com.lowagie.text.pdf.PdfReader;
导入com.lowagie.text.pdf.PdfStamper;
导入java.io.ByteArrayOutputStream;
导入java.net.URL;
导入java.io.IOException;
公共级压模{
公共母版(){
}
公共字节[]stampDocument(字节[]源){
试一试{
PdfReader PdfReader=新PdfReader(orig);
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
PdfStamper PdfStamper=新PdfStamper(pdfReader,BAS);
Image=Image.getInstance(新URL(“http://localhost:8080/IDSG/assets/stamp.jpg"));
图像。设置绝对位置(70f,10f);
图像缩放率(40f);
对于(int i=1;iBruno,感谢您的回答。Close不仅关闭母版,还将所有内容写入BAS。Close抛出了此错误:确实:您希望所有内容都写入BAS
(否则您的PDF文件不完整)。您得到的错误与XMP数据有关。您使用的是哪个版本的iText?我已经很长时间没有看到此错误了。另外:您确定原始PDF中的XMP元数据是正确的吗?Adobe的XMP解析器似乎无法解析它。您好Bruno,很抱歉这么久才返回。它是从网站下载的5.5.6。我即使在Groovy代码中也可以使用它,但是使用了Grails中提供的Itext,一个较旧的版本。Bruno,谢谢你的回答。Close不仅关闭母版,而且将所有内容都写入到BAS。Close抛出了这个错误:确实:你希望所有内容都写入到BAS
(否则你有一个不完整的PDF文件)。您得到的错误与XMP数据有关。您使用的是哪个版本的iText?我已经很长时间没有看到此错误了。另外:您确定原始PDF中的XMP元数据是正确的吗?Adobe的XMP解析器似乎无法解析它。您好Bruno,很抱歉这么久才返回。它是从网站下载的5.5.6。我即使使用Groovy也能正常工作