itext通过pdf模板填充数据并调用打印机打印

使用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 map) {
		
		try {
			// 构建打印请求属性集
			PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
			// 设置打印格式,因为未确定文件类型,这里选择AUTOSENSE
			DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
			// 查找所有的可用打印服务
			// [发送至 OneNote 2013, NPI82AACC (HP LaserJet M1536dnf MFP), Microsoft XPS Document Writer, Fax, CutePDF Writer]
			PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras);
			// 定位默认的打印服务
			PrintService defaultService = null;
			// 获取打印机
			String printer = (String)map.get("printer");
			// 判断打印机是否为空
			if (StringUtils.isBlank(printer)) {
				// 获取默认配置文件打印机
				printer = Global.getPrinterA4();
			}
			
			for (int i = 0; i < printService.length; i++) {
				if (printService[i].getName().contains(printer)) {
					defaultService = printService[i];
					break;
				}
			}
			
			if (defaultService != null) {
				
				//A4纸张
				//pras.add(MediaSize.A4);
				
				// 创建打印作业
				DocPrintJob job = defaultService.createPrintJob();
				// 构造待打印的文件流
				FileInputStream fis = new FileInputStream(printFilePath);
				DocAttributeSet das = new HashDocAttributeSet();
				// 建立打印文件格式
				Doc doc = new SimpleDoc(fis, flavor, das);
				// 打印份数
				if (map.get("Copies") != null) {
					pras.add(new Copies((int) map.get("Copies")));
				} else {
					pras.add(new Copies(1));
				}
				//双面打印
				//pras.add(Sides.DUPLEX);
				if (map.get("duplex") != null) {
					if ((boolean)map.get("duplex")) {
						pras.add(Sides.DUPLEX);
					}
				} else {
					pras.add(Sides.DUPLEX);
				}
				// 进行文件的打印
				job.print(doc, pras);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (PrintException e) {
			e.printStackTrace();
		}
	}
	

}

合同类java代码


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;
	}

}








你可能感兴趣的:(itext,itext,pdf)