使用itext5对生成的pdf模板进行编辑填充数据,一种是通过绝对定位去做,简单的可以,通用性太差,第二种是通过pdf域来填充字段,通用性很强
在使用过程中遇到的问题:
网上都是通过这种字体设置中文的,在生成pdf之后,格式一切都正常,但是用java代码直接调用打印机打印后会出现填充的数据格式和生成的pdf格式不一样
BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
解决方法,添加宋体字体文件,直接调用添加的文件就正常了
String path2 = Thread.currentThread().getContextClassLoader().getResource("SIMSUN.TTC").getPath();
BaseFont baseFont = BaseFont.createFont(path2 + ",1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.bo.ContractBO;
import com.bo.ErrorBO;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
/**
* 修改PDF文件,itext5
* @author 寇
*
*/
public class ModifyPdf {
/**
* 修改合同pdf,向pdf右上角插入二维码图片和编号
* 参考:http://iamxi.iteye.com/blog/1041206
* @param sourcePdfPath 需要修改的pdf路径
* @param qrcodePath 二维码路径
* @param filePath 生成后的文件路径
* @param number 合同编号
*/
public String modifyContractPdf(String sourcePdfPath, String qrcodePath, String number, String filePath) {
try {
SimpleDateFormat dfm = new SimpleDateFormat("yyyy-MM-dd hhmmssSSS");
String path = filePath + "Contract-" + dfm.format(System.currentTimeMillis()) + ".pdf";
// Read file using PdfReader
PdfReader pdfReader = new PdfReader(new URL(sourcePdfPath));
// Modify file using PdfReader
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(path));
// 添加二维码
Image qrcode = Image.getInstance(new URL(qrcodePath));
qrcode.scaleAbsolute(80, 80);
qrcode.setAbsolutePosition(480, 740);
PdfContentByte content = pdfStamper.getUnderContent(1);
//PdfContentByte content = pdfStamper.getOverContent(1);
content.addImage(qrcode);
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
// Font font = new Font(bfChinese, 12, Font.NORMAL);
// BaseFont bfChinese = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
// content.setFontAndSize(bfChinese, 12);
// 添加文字
content.beginText();
content.setFontAndSize(bfChinese, 10);
// 第一种添加文字
// content.showTextAligned(PdfContentByte.ALIGN_CENTER, number, 520, 700, 0);
// 第二种添加文字
content.setTextMatrix(480, 730);
content.showText(number);
content.endText();
pdfStamper.close();
return path;
} catch (IOException e) {
e.printStackTrace();
return "error";
} catch (DocumentException e) {
e.printStackTrace();
return "error";
}
}
/**
* 修改合同pdf,通过域来修改
* 参考: http://blog.csdn.net/xiucaiyao/article/details/45499583
* @param conrtact 合同信息
* @param filePath 合同保存路径
* @param error 错误信息
* @return
*/
public String modifyContractPdf(ContractBO contract, String filePath, List error) {
try {
SimpleDateFormat dfm = new SimpleDateFormat("yyyy-MM-dd hhmmssSSS");
String path = filePath + "Contract-" + dfm.format(System.currentTimeMillis()) + ".pdf";
// 获取pdf
// PdfReader pdfReader = new PdfReader(new URL(contract.getContractPath()));
PdfReader pdfReader = new PdfReader(contract.getContractPath());
// 修改pdf
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(path));
AcroFields fields = pdfStamper.getAcroFields();
// 处理中文
// BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
String path2 = Thread.currentThread().getContextClassLoader().getResource("SIMSUN.TTC").getPath();
BaseFont baseFont = BaseFont.createFont(path2 + ",1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//设置文本域表单的字体
// 对于模板要显中文的,在此处设置字体比在pdf模板中设置表单字体的好处:1.模板文件的大小不变;2.字体格式满足中文要求
fields.setFieldProperty("number", "textfont", baseFont, null);
fields.setFieldProperty("landlordName", "textfont", baseFont, null);
fields.setFieldProperty("landlordPhone", "textfont", baseFont, null);
fields.setFieldProperty("landlordIDCard", "textfont", baseFont, null);
fields.setFieldProperty("price", "textfont", baseFont, null);
String imgInfo = insertImg(pdfStamper, fields, "QRImg", contract.getQrImg(), error);
// 插入二维码图片
if((imgInfo != "success")) {
return imgInfo;
};
// 插入合同编号
fields.setField("number", contract.getNumber());
// 插入房东姓名
fields.setField("landlordName", contract.getLandlordName());
// 插入房东电话
fields.setField("landlordPhone", contract.getLandlordPhone());
// 插入房东身份证
fields.setField("landlordIDCard", contract.getLandlordIDCard());
// 插入租金
fields.setField("price", contract.getPrice());
// 如果为false那么生成的PDF文件还能编辑,一定要设为true
pdfStamper.setFormFlattening(true);
pdfStamper.close();
pdfReader.close();
return path;
} catch (IOException e) {
e.printStackTrace();
error.add(new ErrorBO("error", "系统错误"));
return "error";
} catch (DocumentException e) {
e.printStackTrace();
error.add(new ErrorBO("error", "系统错误"));
return "error";
}
}
/**
* 插入图片
* @param pdfStamper
* @param fields
* @param field 插入的域名
* @param url 插入的图片url
* @param error 错误信息
*/
private String insertImg(PdfStamper pdfStamper, AcroFields fields, String field, String url, List error) {
try {
// 获取图片
List list = fields.getFieldPositions(field);
Image image = Image.getInstance(new URL(url));
for (int i = 0; i < list.size(); i++) {
// 获取所在页数
PdfContentByte under = pdfStamper.getOverContent(list.get(i).page);
// 获取位置
Rectangle signRect = list.get(i).position;
image.setAbsolutePosition(signRect.getLeft(), signRect.getBottom());
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
under.addImage(image);
}
} catch (BadElementException e) {
e.printStackTrace();
error.add(new ErrorBO("error", "系统错误", field));
return "error";
} catch (MalformedURLException e) {
e.printStackTrace();
error.add(new ErrorBO("error", "系统错误", field));
return "error";
} catch (IOException e) {
e.printStackTrace();
if (e.getMessage().contains("502 for URL")) {
error.add(new ErrorBO("502", "网络错误!请稍后再试!", field));
} else if (e.getMessage().contains("504 for URL")) {
error.add(new ErrorBO("504", "网络超时!请稍后再试!", field));
}
return "error";
} catch (DocumentException e) {
e.printStackTrace();
error.add(new ErrorBO("error", "系统错误", field));
return "error";
}
return "success";
}
public static void main(String[] args) {
new ModifyPdf().modifyContractPdf(new ContractBO("NO:ASZ001397890", "1250", "张三3", "15112345679", "610622199112039053", "http://localhost:8080/rest/qr/code/weixin/qr", "C://Users/miju/Desktop/editcontract2.pdf"), "C://Users/miju/Desktop/", new ArrayList());
new PrintFile().print("C://Users/miju/Desktop/Contract2.pdf", new HashMap
调用打印机打印功能
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Sides;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import com.gehouse.smartdevice.config.Global;
/**
* 调用打印机打印文件
* @author 寇
*
*/
public class PrintFile {
/**
* 调用打印机进行打印
* @param printFilePath 打印文件路径
* @param printFilePath 打印参数
*/
public void print(String printFilePath, Map
package com.bo;
/**
* 合同类
*
* @author kou
*
*/
public class ContractBO {
// 合同编号
private String number;
// 租金
private String price;
// 房东姓名
private String landlordName;
// 房东电话
private String landlordPhone;
// 房东身份证
private String landlordIDCard;
// 二维码路径
private String qrImg;
// 合同路径
private String contractPath;
public ContractBO() {
super();
}
public ContractBO(String number, String price, String landlordName,
String landlordPhone, String landlordIDCard, String qrImg,
String contractPath) {
super();
this.number = number;
this.price = price;
this.landlordName = landlordName;
this.landlordPhone = landlordPhone;
this.landlordIDCard = landlordIDCard;
this.qrImg = qrImg;
this.contractPath = contractPath;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getLandlordName() {
return landlordName;
}
public void setLandlordName(String landlordName) {
this.landlordName = landlordName;
}
public String getLandlordPhone() {
return landlordPhone;
}
public void setLandlordPhone(String landlordPhone) {
this.landlordPhone = landlordPhone;
}
public String getLandlordIDCard() {
return landlordIDCard;
}
public void setLandlordIDCard(String landlordIDCard) {
this.landlordIDCard = landlordIDCard;
}
public String getQrImg() {
return qrImg;
}
public void setQrImg(String qrImg) {
this.qrImg = qrImg;
}
public String getContractPath() {
return contractPath;
}
public void setContractPath(String contractPath) {
this.contractPath = contractPath;
}
}
package com.bo;
/**
* 错误信息类
*
* @author kou
*
*/
public class ErrorBO {
// 错误代码
private String code;
// 错误信息
private String message;
// 错误来源
private String from;
public ErrorBO() {
super();
}
public String getCode() {
return code;
}
public ErrorBO(String code, String message) {
super();
this.code = code;
this.message = message;
}
public ErrorBO(String code, String message, String from) {
super();
this.code = code;
this.message = message;
this.from = from;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
}