pdf根据指定标记替换内容重新生成pdf

生成空白图片遮盖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<float[]> 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<float[]> getKeyWords(String filePath, final String KEY_WORD,final String fonts) {
		arrays = new ArrayList<float[]>();
		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<float[]> 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<float[]> result = null;
			// 页数是从1开始的
			for (int i = 1; i <= reader.getNumberOfPages(); i++) {
				// 获得pdfstamper在当前页的上层打印内容.也就是说 这些内容会覆盖在原先的pdf内容之上.
				PdfContentByte over = stamper.getOverContent(i);
				List<Mark> 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;
	}

}

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现 Java 和 HTML 动态模板替换生成 PDF,可以使用以下步骤: 1. 使用 Java 代码读取 HTML 模板文件,并将模板中需要动态替换内容标记出来,例如使用 ${} 包含起来。 2. 使用 Java 代码获取需要替换的数据,例如从数据库中查询数据或者从其他数据源获取数据。 3. 使用 Java 代码将获取到的数据替换到 HTML 模板中需要替换的位置,即替换 ${} 中的内容。 4. 使用 Java 代码将替换后的 HTML 保存为 PDF 文件。 下面是一个简单的示例代码,假设有一个名为 template.html 的 HTML 模板文件,其中有两个动态替换的位置:${name} 和 ${age}。 ```java import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import com.itextpdf.html2pdf.HtmlConverter; public class PdfGenerator { public static void main(String[] args) throws IOException { // 读取 HTML 模板文件 String html = new String(Files.readAllBytes(Paths.get("template.html")), StandardCharsets.UTF_8); // 构造数据 Map<String, String> data = new HashMap<>(); data.put("name", "张三"); data.put("age", "20"); // 替换 HTML 模板中的动态内容 for (Map.Entry<String, String> entry : data.entrySet()) { html = html.replace("${" + entry.getKey() + "}", entry.getValue()); } // 将替换后的 HTML 保存为 PDF 文件 try (FileOutputStream fos = new FileOutputStream("output.pdf")) { HtmlConverter.convertToPdf(html, fos); } } } ``` 在这个示例中,使用了 iText 库将 HTML 转换为 PDF。需要将 iText 库添加到项目中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值