您的位置:首页 > 其它

iText自动生成多页PDF时,解决背景(水印)只显示第一页的问题

2017-11-21 18:14 1261 查看
怎么样自动生成PDF,在我的上一篇博客中有些,这里我主要是记录一下当用itext自动生成PDF文档有多页的的时候,背景(水印)只在第一页显示的问题,这里的背景就是一张已知路径的图片,

下面贴上只有一页有背景图时的部分代码:

Document document = new Document(PageSize.A4);
// 设置pdf的背景图片
Image image = Image.getInstance(picPath);//picPath就是背景图片的路径
image.setAlignment(image.UNDERLYING);
// 设置图片在A4的大小填充完全
image.setAbsolutePosition(0,0);
image.scaleAbsolute(595,842);
PdfWriter pdfwriter = PdfWriter.getInstance(document,
new FileOutputStream(pdfFile));
pdfwriter.setViewerPreferences(PdfWriter.HideToolbar);
document.open();  document.add(image);// 添加图片

我开始是这样写的,然后当PDF文档有多页的时候,背景图片就只有第一页有显示,我去网上找了好久,发现了一种说法是写一个java类,然后继承PdfPageEventHelper,然后自己写方法,这样每次PDF有newPage生成的时候,就会调用。大概是这样说的,我当时也是没有看懂,感觉没有说具体,也不说重写什么方法;然后我大概按照他说的方法摸索去试就如下方代码,然后也成功了:

这个是我定义的java类

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.IOException;

public class BackGroundImage extends PdfPageEventHelper {

private String picPath = "";

public String getPicPath() {
return picPath;
}

public void setPicPath(String picPath) {
this.picPath = picPath;
}

public BackGroundImage(){

}

public BackGroundImage(String path){
this.picPath = path;
}

@Override
public void onStartPage(PdfWriter pdfWriter, Document document) {
try {
Image image = Image.getInstance(picPath);
image.setAlignment(image.UNDERLYING);
image.setAbsolutePosition(0,0);
image.scaleAbsolute(595,842);
// 设置图片旋转
//            image.setRotation((float) (-Math.PI / 6));
document.add(im
4000
age);
} catch (BadElementException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}

super.onStartPage(pdfWriter, document);
}
}
我不知道重写什么方法,我去看父类中有个叫onStartPage方法,翻译过来有点就像新开始页面要执行的,所以试了试,这个新写的类这样引用:

Document document = new Document(PageSize.A4);
// 设置pdf的背景图片
//            Image image = Image.getInstance(picPath);
//            image.setAlignment(image.UNDERLYING);
//            image.setAbsolutePosition(0,0);
//            image.scaleAbsolute(595,842);

PdfWriter pdfwriter = PdfWriter.getInstance(document,
new FileOutputStream(pdfFile));
pdfwriter.setViewerPreferences(PdfWriter.HideToolbar);
pdfwriter.setPageEvent(new BackGroundImage(picPath));
document.open();
//            document.add(image);


这样我生成的多页PDF就都有背景图片了。

这种是直接把图片作为背景,有一些是直接生成水印而不是图片,下面这段代码也许有点帮助,我改了一下,直接把水印转化为图片保存,也可以直接以流的方式插入,可以自己研究一下,我就直接把生成水印的全部代码粘上了:

(请勿直接复制使用)

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.net.URLDecoder;

/**
* 添加水印
*/
public class WaterMark {

/**
* 通用的水印标注
*
* @param request
* @param response
* @param billno
*/
public static String waterMarkStaticDouble(
HttpServletRequest request, HttpServletResponse response, String billno, boolean dark) {
String retrunVal = "";
String fontName = "Arial-Black";
int fontStyle = 36;
Color color = new Color(171, 235, 231);
int fontSize = 78;
int x = 110;
int y = -150;
float alpha = 1.0f;
int degree = -35;
String staffId = "java开发交流公司";
try {
response.setContentType("image/jpeg");
String basePath = request.getRealPath("/")
.toLowerCase().replaceAll("WEB-INF/classes/".toLowerCase(),
"").trim();
basePath = URLDecoder.decode(basePath.replace("/", "\\"));

if (basePath.startsWith("\\")) {
basePath = basePath.substring(1, basePath.length());
}
File f = new File(basePath
+ "WebLibrary\\images\\security_image2.jpg");

//            BufferedImage bgimg = ImageIO.read(f);
BufferedImage bgimg = new BufferedImage(1000, 520, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bgimg.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0,0,1000,520);
g.dispose();

BufferedImage currentImg = getText(staffId, bgimg, color, (fontSize - 10), x, y);
y += (fontSize - 30);
x += -70;
currentImg = getText(billno, bgimg, color, (fontSize - 25), x, y);

y += 320;
x += -200;
color = new Color(151, 215, 211);
currentImg = getText(staffId, bgimg, color, (fontSize - 10), x, y);
y += (fontSize - 30);
x += -70;
currentImg = getText(billno, bgimg, color, (fontSize - 25), x, y);

currentImg = rotateImg(currentImg, degree, Color.white);
File folder = new File(basePath+"WebLibrary\\images\\temppic\\");
if(!folder.exists()){
folder.mkdirs();
}
// 输出到指定的本地路径
ImageIO.write(currentImg, "jpg", new File(folder+"\\bg"+billno+".jpg"));
// 返回图片路径
retrunVal = folder+"\\bg"+billno+".jpg";
} catch (Exception ex) {
System.out.println("加水印报错:" + ex.toString());
}
return retrunVal;
}

/**
* 艺术字体
*
* @param pressText
* @param image
* @param color
* @param fontSize
* @param x
* @param y
* @return
*/
public static BufferedImage getText(String pressText, BufferedImage image, Color color, int fontSize, int x, int y) {
Graphics2D g = image.createGraphics();
java.awt.Font f = new java.awt.Font("楷体", Font.BOLD, fontSize);
GlyphVector v = f.createGlyphVector(g.getFontMetrics(f).getFontRenderContext(), pressText);
Shape shape = v.getOutline();
Rectangle bounds = shape.getBounds();
g.translate(
(image.getWidth() - (getLength(pressText) * fontSize)) / 2 + x,
(image.getHeight() - fontSize) / 2 + y
);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.WHITE);
g.fill(shape);
g.setColor(color);
g.setStroke(new BasicStroke(3));//设置粗细
g.draw(shape);
return image;
}

/**
* 获取字符串长度
*
* @param text
* @return
*/
public static int getLength(String text) {
int length = 0;
for (int i = 0; i < text.length(); i++) {
if (new String(text.charAt(i) + "").getBytes().length > 1) {
length += 2;
} else {
length += 1;
}
}
return length / 2;
}

/**
* 显示水印的util 开始
*/
public static BufferedImage rotateImg(BufferedImage image, int degree, Color bgcolor) {

int iw = image.getWidth();//原始图象的宽度
int ih = image.getHeight();//原始图象的高度
int w = 0;
int h = 0;
int x = 0;
int y = 0;
degree = degree % 360;
if (degree < 0) degree = 360 + degree;//将角度转换到0-360度之间
double ang = degree * 0.0174532925;//将角度转为弧度

/**
*确定旋转后的图象的高度和宽度
*/

if (degree == 180 || degree == 0 || degree == 360) {
w = iw;
h = ih;
} else if (degree == 90 || degree == 270) {
w = ih;
h = iw;
} else {
int d = iw + ih;
w = (int) (d * Math.abs(Math.cos(ang)));
h = (int) (d * Math.abs(Math.sin(ang)));
}

x = (w / 2) - (iw / 2);//确定原点坐标
y = (h / 2) - (ih / 2);
BufferedImage rotatedImage = new BufferedImage(w, h, image.getType());
Graphics gs = rotatedImage.getGraphics();
gs.setColor(bgcolor);
gs.fillRect(0, 0, w, h);//以给定颜色绘制旋转后图片的背景
AffineTransform at = new AffineTransform();
at.rotate(ang, w / 2, h / 2);//旋转图象
at.translate(x, y);
AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
op.filter(image, rotatedImage);
image = rotatedImage;
return image;
}
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: