iText自动生成多页PDF时,解决背景(水印)只显示第一页的问题
2017-11-21 18:14
1261 查看
怎么样自动生成PDF,在我的上一篇博客中有些,这里我主要是记录一下当用itext自动生成PDF文档有多页的的时候,背景(水印)只在第一页显示的问题,这里的背景就是一张已知路径的图片,
下面贴上只有一页有背景图时的部分代码:
我开始是这样写的,然后当PDF文档有多页的时候,背景图片就只有第一页有显示,我去网上找了好久,发现了一种说法是写一个java类,然后继承PdfPageEventHelper,然后自己写方法,这样每次PDF有newPage生成的时候,就会调用。大概是这样说的,我当时也是没有看懂,感觉没有说具体,也不说重写什么方法;然后我大概按照他说的方法摸索去试就如下方代码,然后也成功了:
这个是我定义的java类
这样我生成的多页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; } }
相关文章推荐
- springMVC中itext生成PDF,根本上解决中文乱码以及不显示问题
- iText+Flying Saucer生成pdf文档,中文不显示和不自动换行问题
- iText7 生成 PDF 文件,解决各种操作系统中文问题,控制指定位置显示图片、文字、图文混排
- 解决JasperReport生成PDF文件,中文不能显示的问题
- 利用jasperreports报表生成pdf文档中文不能显示问题解决方法
- 用Adobe Acrobat DC快速生成合同模板、itext导出pdf,解决项目中合同问题
- java 用itext-asian解决itext pdf中文不显示问题
- 利用itext导出HTML到PDF,解决中文不显示和中文不换行的问题
- 使用itext根据freemarks模版生成pdf,表格产生跨页问题解决方法
- 使用itext将html生成pdf中文换行问题解决方案
- itext应用HTML模版生成PDF并加水印,处理了中文问题
- ITEXT5.5.8转html为pdf文档解决linux不显示中文问题
- 通过swagger2markup+asciidoctorj生成html和pdf文档并解决asciidoctorj生成的pdf文件中文显示不全问题(maven方式及java代码方式)
- 用itext生成带表格的PDF,并显示中文问题
- 使用itext将html生成pdf中文换行问题解决方案2
- 解决 iReport 生成 pdf 时显示不出中文的问题
- jasperreport 生成PDF汉字不显示问题的解决
- 用itextpdf生成水印来代替pdf的替换问题
- 用itext生成pdf报表下篇(解决中文问题)
- 【iReport学习一】iReport 3.7版本中,PDF中文显示问题解决方法