使用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 PdfReaderPdfReader pdfReader = new PdfReader(new URL(sourcePdfPath));// Modify file using PdfReaderPdfStamper 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<ErrorBO> 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());// 修改pdfPdfStamper 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文件还能编辑,一定要设为truepdfStamper.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<ErrorBO> error) {try {// 获取图片List<AcroFields.FieldPosition> 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<ErrorBO>());new PrintFile().print("C://Users/miju/Desktop/Contract2.pdf", new HashMap<Object, Object>());}}

调用打印机打印功能


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<Object, Object> map) {try {// 构建打印请求属性集PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();// 设置打印格式,因为未确定文件类型,这里选择AUTOSENSEDocFlavor 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通过pdf模板填充数据并调用打印机打印相关推荐

  1. Android iText向pdf模板插入数据和图片

    需求 这些日志在写App程序,有这么一个需求,就是需要生成格式统一的一个pdf文件,并向固定表格中填充数据,并且再在pdf中追加两页图片. 方案 手工设计一个pdf模板,这个具体步骤就不再赘述,可以网 ...

  2. Java--依照PDF模板进行数据的填充并输出

    Java–依照PDF模板进行数据的填充并输出 今天因为有一个逻辑问题迟迟没有定下来,老板去了学习,所以闲着也是闲着,就抽空学习研究了下用Java输出PDF文件的技术. 引入相应的Jar包 这是导出pd ...

  3. 使用iTextPdf为Pdf模板填充表单项

    说明 日常开发中,通常会有动态填充Pdf表单的需求,程序可根据用户的输入或后台数据库的内容,动态.批量向Pdf模板中填充内容. 这里简单介绍一下Pdf模板的制作,以及通过iTextPdf组件给pdf ...

  4. java pdf 报表_关于Java向PDF模板写入数据,以及java制作pdf报表的问题

    1.关于java向PDF模板写入数据 写的特别全一步一步来就行. (1)首先下载一个pdf编辑工具Adobe Acrobat DC (2)准备一个pdf模板文件(你可以把自己创建一个只有表头没有内容的 ...

  5. 利用poi向word模板填充数据

    java基于POI实现向word模板填充数据 在做项目的时候遇到需要将多张表单导出为word,就想到了这个方法. 注意:XWPFDocument不支持doc类型文档,做模板的时候要另存为docx. 示 ...

  6. Java poi word模板填充数据、复制行删除行

    Java poi word模板填充数据 1.明细表格式 ${list_xxxxx} 普通格式 ${xxxxxx} 2.replaceInTable方法中 table.removeRow(2); 第三行 ...

  7. java如何根据模板填充数据生成word文档

    java根据模板填充数据生成word文档 这篇文章干什么? 思路总览 1.准备word模板 2.转换文件格式 3.编写代码 补充--下载流 这篇文章干什么?   使用代码将word模板内容进行替换,并 ...

  8. Java使用自定义Excel模板填充数据

    Java使用自定义Excel模板填充数据 上期我们说到使用POI简单的制作一个Excel,这里我们教林外一种方法,就是把Excel写好定为模板,直接填充数据. 老样子还是要添加POM依赖 <de ...

  9. EasyExcel使用模板填充数据导出遇到的坑

    EasyExcel使用模板填充数据导出遇到的坑 1.最近需求涉及excel的导出,所以选择用阿里的EasyExcel框架来使用是比较方便的,这个框架封装了许多方法来供我们使用,比传统POI简单许多 2 ...

最新文章

  1. oracle实例没有连到监听上6,oracle LISTENER未监听到oracle实例问题解决
  2. 用C语言写PHP扩展
  3. python无限循环条件循环_Python - 条件控制、循环语句 - 第十二天
  4. libpcap实现机制及接口函数
  5. 构建本地缓存java_Java8简单的本地缓存实现
  6. insert时调用本身字段_「技术篇」ETL工具Kettle数据对比同步以及Java程序中调用
  7. java main 如何不退出_为什么java main主线程退出了子线程还能运行;golang main结束所有协程都被结束了...
  8. [IOI2018] werewolf 狼人
  9. (转)腾讯2011.10.15校园招聘会笔试题
  10. 机器学习 —— 浅谈贝叶斯和MCMC
  11. JDK1.8 HashSet
  12. isDate()函数
  13. 整型索引查询mysql是不是快点_图解Mysql索引的数据结构!看不懂你来找我
  14. ubuntu设置始终亮屏_教你在Ubuntu系统下保存屏幕亮度设置
  15. 网校系统开发如何做才能保证系统稳定发展
  16. 股票6题(Aced)
  17. C语言:编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登陆成功,如果三次均输入错误,则退出程序)
  18. 0基础用vagrant 快速构建larval开发环境 (我杨某人尽力描述了,都有从0介绍)
  19. linux 透明 网关 配置,透明网关配置
  20. CVPR2020目标检测方向论文

热门文章

  1. Day02:变量和赋值
  2. 连上手机热点,但显示无internet
  3. 网络流重制版:最大流Dinic,以及EK、Dinic时间复杂度的证明(含坑)
  4. oracle查看锁表的sql
  5. iotBaidu问题小结
  6. 阿里云账号怎么注册?新手注册流程多方法
  7. 创建一个swarm集群
  8. 代码写了十余年,真心话儿聊不完
  9. mysql时间字段使用索引
  10. 爱畔平板android,智能语音更贴心 华为平板M5青春版给父母新享受