生成空白图片遮盖pdf标记
package org.plugbase.base.pdf;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
/**
* 生成空白图片
*
*
*/
public class ImageUtil {
public static void main(String[] args) throws Exception {
// createImage("3158商机通", "d:/a.png");
}
/**
* 功能:主要用于生成空白图片
*
* @param pathname
* 图片路劲
* @param imgContent
* 模板标记内容如:{模板}
* @throws Exception
*/
public static void createImage(String pathname, String imgContent,String fonts) throws Exception {
//Font font = new Font("宋体", Font.PLAIN, 11);
Font font = Loadfont.loadFont(fonts, 11);
if (font == null){
return;
}
File outFile = new File(pathname);
// 获取font的样式应用在str上的整个矩形
Rectangle2D r = font.getStringBounds(imgContent,
new FontRenderContext(AffineTransform.getScaleInstance(1, 1), false, false));
int unitHeight = (int) Math.floor(r.getHeight());// 获取单个字符的高度
// 获取整个str用了font样式的宽度这里用四舍五入后+1保证宽度绝对能容纳这个字符串作为图片的宽度
int width = (int) Math.round(r.getWidth()) + 1;
int height = unitHeight + 1;// 把单个字符的高度+3保证高度绝对能容纳字符串作为图片的高度
// 创建图片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);// 先用白色填充整张图片,也就是背景
// g.setColor(Color.black);// 在换成黑色
// g.setFont(font);// 设置画笔字体
// g.drawString(str, 0, font.getSize());// 画出字符串
g.dispose();
ImageIO.write(image, "png", outFile);// 输出png图片
}
}
package org.plugbase.base.pdf;
import java.awt.Font;
import java.io.File;
import java.io.FileInputStream;
/**
* @ClassName: Loadfont
* @Description:
* @author liuyajun
* @date 2016年12月21日 上午9:08:43
*
*/
public class Loadfont {
public static Font loadFont(String fontFileName, float fontSize){ // 第一个参数是外部字体名,第二个是字体大小
try {
File file = new File(fontFileName);
FileInputStream aixing = new FileInputStream(file);
Font dynamicFont = Font.createFont(Font.TRUETYPE_FONT, aixing);
Font dynamicFontPt = dynamicFont.deriveFont(fontSize);
aixing.close();
return dynamicFontPt;
} catch (Exception e){// 异常处理
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
Font font= loadFont("D:/home/java/contract/web/fonts/simsun.ttf",11);
System.out.println(font.getFontName());
}
}
根据标记定位标记所在pdf文件中的坐标
package org.plugbase.base.pdf;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.itextpdf.awt.geom.Rectangle2D.Float;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.SimpleTextExtractionStrategy;
import com.itextpdf.text.pdf.parser.TextExtractionStrategy;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
/**
* 定坐标
*
* @author WANCSP
*
*/
public class PdfPlace {
private static StringBuffer str = null;
private static int i = 0;
static List arrays = null;
static String sb;
static int state = 0;
static float x = 0;
static float y = 0;
/**
* 功能:根据关键字定位坐标
*
* @param filePath
* pdf路径
* @param KEY_WORD
* 关键字
* @return
*/
static List getKeyWords(String filePath, final String KEY_WORD,final String fonts) {
arrays = new ArrayList();
try {
PdfReader pdfReader = new PdfReader(filePath);
int pageNum = pdfReader.getNumberOfPages();
PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
for (i = 1; i <= pageNum; i++) {
str = new StringBuffer();
pdfReaderContentParser.processContent(i, new RenderListener() {
@Override
public void renderText(TextRenderInfo textRenderInfo) {
// String text =
// textRenderInfo.getBaseline().toString();
String text = textRenderInfo.getText(); // 整页内容
if (text != null) {
Float boundingRectange = null;
str.append(text);
/*if (str.toString().contains("{")){
String[] s = str.toString().split("\\{");
state = s.length==1?0:1;
if(state ==0){
state = 1;
boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
x = boundingRectange.x;
y = boundingRectange.y;
}
}
if (str.toString().contains("}") && state ==1){
state = 0;
}*/
if (str.toString().contains(KEY_WORD)) {
boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
//Font font = new Font("宋体", Font.PLAIN, 10);
Font font = Loadfont.loadFont(fonts, 11);
if (font == null){
return;
}
// 获取font的样式应用在str上的整个矩形
Rectangle2D r = font.getStringBounds(KEY_WORD,
new FontRenderContext(AffineTransform.getScaleInstance(1, 1), false, false));
// 获取整个str用了font样式的宽度这里用四舍五入后+1保证宽度绝对能容纳这个字符串作为图片的宽度
int width = (int) Math.round(r.getWidth());
float[] resu = new float[3];
resu[0] = boundingRectange.x-width;
resu[1] = boundingRectange.y;
resu[2] = i;
arrays.add(resu);
str = new StringBuffer();
}
}
}
@Override
public void renderImage(ImageRenderInfo arg0) {
// TODO Auto-generated method stub
}
@Override
public void endTextBlock() {
}
@Override
public void beginTextBlock() {
}
});
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return arrays;
}
static String pdfcontent(String filePath) {
PdfReader reader;
String pageText = null;
try {
reader = new PdfReader(filePath);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
TextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
int pageCount = reader.getNumberOfPages();
for (int i = 1; i <= pageCount; i++) {
TextExtractionStrategy result = parser.processContent(i, strategy);
pageText = result.getResultantText();
System.out.println(pageText);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return pageText;
}
public static void main(String[] args) throws IOException {
/*
List ff = getKeyWords("D:\\ceshi\\3158商机通合同模板(4800元 年)2.pdf", "{服务项目}");
for (float[] f : ff) {
System.out.println(f[0] + "----" + f[1] + "-----" + f[2]);
}
System.out.println(sb);*/
}
}
项目中的实现
package org.plugbase.base.pdf;
import java.io.FileOutputStream;
import java.util.List;
import org.plugbase.base.util.Config;
import org.plugbase.contract.bean.Contract;
import org.plugbase.contract.bean.Mark;
import org.plugbase.contract.bean.Title;
import org.plugbase.contract.util.MarkSQLMapper;
import org.plugbase.contract.util.TitleSQLMapper;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
public class PDFUtil {
private static final int width = -7;//本地标记x轴调整
// 项目放到linux 必须用服务器标记x轴;
//private static final int width = 12;// 服务器标记x轴调整
private static final int height = 2;// 标记y轴调整
private static final int heightzhang = 60;// 标记y轴调整合同章
/**
* 功能:替换pdf指定标签内容
*
* @param over
* PdfContentByte
* @param result
* 坐标
* @param font
* 字体
* @param page
* pdf页码
* @param img
* 图片路劲
* @param imgContent
* 模板标记内容如:{模板}
* @return
*/
public static PdfContentByte pdfContentByte(String fonts,PdfContentByte over, float[] result, Font font, String str, int page,
String img, String imgContent) {
try {
if (result != null) {
float x = result[0];
float y = result[1];
ImageUtil.createImage(img, imgContent,fonts);
Image image = Image.getInstance(img);
image.setAbsolutePosition(x - width, y - height);
over.addImage(image);
// 开始写入文本
over.beginText();
// 设置字体和大小
over.setFontAndSize(font.getBaseFont(), 10);
// 设置字体的输出位置
over.setTextMatrix(x-width, y);
// 要输出的text
over.showText(str);
System.out.println(str+":"+x+","+y);
over.endText();
}
} catch (Exception e) {
e.printStackTrace();
}
return over;
}
/**
* 功能:根据标记修改pdf指定内容
*
* @param contract
* 合同
* @param type
* 1:创建合同 2:审核合同
* @return
*/
public static boolean PdfSomain(Contract contract, int type) {
if (contract == null || type == 0) {
return false;
}
Config config = Config.configure("template.properties");
String formal = config.get("formal");
String fonts = config.get("fonts");
String preview = config.get("preview");
String QRcode = config.get("QRcode");
String pdf = config.get("pdf");
if (formal == null || formal.equals("") || fonts == null || fonts.equals("") || preview == null
|| preview.equals("") || QRcode == null || QRcode.equals("") || pdf == null || pdf.equals("")) {
return false;
}
Title title = TitleSQLMapper.getByIdTitle(contract.getTitleID());
if (title == null || title.getUrls() == null || title.getUrls().equals("")) {
return false;
}
String filePath = null;
if (type == 1) {
filePath = pdf + title.getUrls();
} else {
filePath = preview + contract.getNumName() + ".pdf";
}
String img = pdf + "/images/kbtp.png";
if (contract.getQRcode() == null || contract.getQRcode().equals("") || contract.getNumName() == null
|| contract.getNumName().equals("")) {
return false;
}
QRcode = QRcode + contract.getQRcode();
String newpdf = "";
if (type == 1) {
newpdf = preview + contract.getNumName() + ".pdf";
} else {
newpdf = formal + contract.getNumName() + ".pdf";
}
// 创建一个pdf读入流
PdfReader reader;
try {
reader = new PdfReader(filePath);
// 根据一个pdfreader创建一个pdfStamper.用来生成新的pdf.
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(newpdf));
BaseFont bf = BaseFont.createFont(fonts, BaseFont.IDENTITY_H, BaseFont.EMBEDDED); // set
// font
// baseFont不支持字体样式设定.但是font字体要求操作系统支持此字体会带来移植问题.
Font font = new Font(bf, 10);
font.setStyle(Font.BOLD);
font.getBaseFont();
List result = null;
// 页数是从1开始的
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
// 获得pdfstamper在当前页的上层打印内容.也就是说 这些内容会覆盖在原先的pdf内容之上.
PdfContentByte over = stamper.getOverContent(i);
List list = MarkSQLMapper.selectAllMark();
int size = list.size();
if (list == null || size == 0) {
return false;
}
String str = "";
//String pdfcontent = PdfPlace.pdfcontent(filePath);
if (type == 1) {
for (int j = 0; j < size; j++) {
Mark mark = list.get(j);
//if(pdfcontent !=null && pdfcontent.contains(mark.getMarks())){
result = PdfPlace.getKeyWords(filePath, mark.getMarks(),fonts);
if (result != null && result.size() > 0) {
if (mark.getContract().equals("numName")) { //合同编号
if (contract.getNumName() != null) {
str = contract.getNumName();
}
} else if (mark.getContract().equals("partyA")) {//甲方公司
if (contract.getPartyA() != null) {
str = contract.getPartyA();
}
} else if (mark.getContract().equals("buyName")) {//购买服务
if (contract.getBuyName() != null) {
str = contract.getBuyName();
}
} else if (mark.getContract().equals("generalizeName")) {//推广项目名称
if (contract.getGeneralizeName() != null) {
str = contract.getGeneralizeName();
}
} else if (mark.getContract().equals("deadline")) {//服务期限
if (contract.getDeadline() > 0) {
str = contract.getDeadline()+"个月";
}
} else if (mark.getContract().equals("startingTime")) {//服务起始时间
if (contract.getStartingTime() != null) {
str = contract.getStartingTime();
}
} else if (mark.getContract().equals("checkoutTime")) {//付款时间
if (contract.getCheckoutTime() != null) {
str = contract.getCheckoutTime();
}
} else if (mark.getContract().equals("cost")) {//服务费用
if (contract.getDouble_cost() != null) {
str = contract.getDouble_cost();
}
} else if (mark.getContract().equals("invoice")) {//发票信息
if (contract.getInvoice() != null) {
str = contract.getInvoice();
}
} else if (mark.getContract().equals("money")) {//大写金额
if (contract.getMoney() != null) {
str = contract.getMoney();
}
} else if (mark.getContract().equals("account")) {//银行账号
if (contract.getAccount() != null) {
str = contract.getAccount();
}
} else if (mark.getContract().equals("accountName")) {//开户名
if (contract.getAccountName() != null) {
str = contract.getAccountName();
}
} else if (mark.getContract().equals("accountBank")) {//开户行
if (contract.getAccountBank() != null) {
str = contract.getAccountBank();
}
} else if (mark.getContract().equals("companyName")) {//乙方
if (contract.getCompanyName() != null) {
str = contract.getCompanyName();
}
}
if (!mark.getContract().equals("empName")){
for (int k = 0; k < result.size(); k++) {
if (result.get(k)[2] == i){
pdfContentByte(fonts,over, result.get(k), font, str, i, img, mark.getMarks());
}
}
}
//}
}
}
} else {
if (i == 1) {
//添加二维码底部文字,底部文字与二维码高度保持9px,避免被覆盖
over.beginText();
over.setFontAndSize(font.getBaseFont(), 10);
over.setTextMatrix(60, 741);
over.showText("扫一扫,辨真伪");
over.endText();
//添加二维码图片
Image image = Image.getInstance(QRcode);
image.setAbsolutePosition(65, 750);
image.scaleAbsolute(60, 60);
over.addImage(image);
}
for (int j = 0; j < size; j++) {
Mark mark = list.get(j);
//if(pdfcontent !=null && pdfcontent.contains(mark.getMarks())){
result = PdfPlace.getKeyWords(filePath, mark.getMarks(),fonts);
if (result != null && result.size() > 0) {
for (int k = 0; k < result.size(); k++) {
if (mark.getContract().equals("empName")) {//合同章位置
float x = result.get(k)[0];
float y = result.get(k)[1];
if (result.get(k)[2] == i){
//生成空白图片遮盖标记
ImageUtil.createImage(img, mark.getMarks(),fonts);
Image image = Image.getInstance(img);
image.setAbsolutePosition(x - width, y - height);
over.addImage(image);
if (contract.getAccountUrls() != null) {
//插入公章
String urls = pdf + contract.getAccountUrls();
image = Image.getInstance(urls);
image.setAbsolutePosition(x - width, y - heightzhang);
image.scaleAbsolute(120, 120);
over.addImage(image);
}
}
}
}
}
}
}
//}
}
stamper.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
}