700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > itextword加公章 java_使用itext和freemarker来根据Html模板生成PDF文件 加水印 印章...

itextword加公章 java_使用itext和freemarker来根据Html模板生成PDF文件 加水印 印章...

时间:2020-02-29 15:14:03

相关推荐

itextword加公章 java_使用itext和freemarker来根据Html模板生成PDF文件 加水印 印章...

org.xhtmlrenderer

flying-saucer-pdf-itext5

9.1.18

org.freemarker

freemarker

2.3.27-incubating

将html模板和数据进行匹配,然后用流的方式生成PDF文件

生成PDF工具类源码:

package com.lifengdi.file.pdf;

import com.itextpdf.text.*;

import com.itextpdf.text.pdf.*;

import com.itextpdf.text.pdf.parser.PdfReaderContentParser;

import com.lifengdi.config.GlobalConfig;

import com.lifengdi.config.PDFFontConfig;

import com.lifengdi.config.SystemConfig;

import com.lifengdi.file.pdf.listener.MyTextLocationListener;

import com.lifengdi.model.pdf.Location;

import com.lifengdi.model.pdf.PDFStamperConfig;

import com.lifengdi.model.pdf.PDFTempFile;

import com.lifengdi.model.pdf.PDFWatermarkConfig;

import com.lifengdi.util.GeneratedKey;

import com.lifengdi.util.MyStringUtil;

import freemarker.template.Configuration;

import freemarker.template.Template;

import freemarker.template.TemplateExceptionHandler;

import lombok.extern.slf4j.Slf4j;

import mons.io.FileUtils;

import mons.lang3.StringUtils;

import org.springframework.core.io.ClassPathResource;

import org.ponent;

import org.xhtmlrenderer.pdf.ITextFontResolver;

import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.annotation.Resource;

import java.io.*;

import java.util.Objects;

/**

* 生成PDF工具类

*

* @author 李锋镝

* @date Create at 10:42 /5/9

*/

@Component

@Slf4j

public class HtmlToPDF {

@Resource

private SystemConfig systemConfig;

@Resource

private GeneratedKey generatedKey;

/**

* 模板和数据匹配

*

* @param data 数据

* @param pdfTempFile pdfTempFile

* @return html

*/

public String matchDataToHtml(Object data, PDFTempFile pdfTempFile) {

StringWriter writer = new StringWriter();

String html;

try {

// FreeMarker配置

Configuration config = new Configuration(Configuration.VERSION_2_3_25);

config.setDefaultEncoding(GlobalConfig.DEFAULT_ENCODING);

// 注意这里是模板所在文件夹,不是模版文件

String parentPath, tempFileName = pdfTempFile.getTemplateFileName();

if (MyStringUtil.isHttpUrl(pdfTempFile.getTemplateFileParentPath())) {

parentPath = systemConfig.getLocalTempPath();

} else {

parentPath = pdfTempFile.getTemplateFileParentPath();

// 将项目中的文件copy到服务器本地

if (!parentPath.endsWith(File.separator))

parentPath = parentPath + File.separator;

String localTempPath = systemConfig.getLocalTempPath();

String target = (localTempPath.endsWith(File.separator) ? localTempPath : localTempPath + File.separator) + tempFileName;

InputStream tempFileInputStream = new ClassPathResource(parentPath + tempFileName).getInputStream();

FileUtils.copyInputStreamToFile(tempFileInputStream, new File(target));

}

log.info("模板和数据匹配,模板文件parentPath:{}", parentPath);

config.setDirectoryForTemplateLoading(new File(systemConfig.getLocalTempPath()));

config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

config.setLogTemplateExceptions(false);

// 根据模板名称 获取对应模板

Template template = config.getTemplate(tempFileName);

// 模板和数据的匹配

template.process(data, writer);

writer.flush();

html = writer.toString();

return html;

} catch (Exception e) {

log.error("PDF模板和数据匹配异常", e);

} finally {

try {

writer.close();

} catch (IOException e) {

log.error("StringWriter close exception.", e);

}

}

return null;

}

/**

* 生成PDF

*

* @param html html字符串

* @param targetFileName 目标文件名

* @return 生成文件的名称

* @throws Exception e

*/

public String createPDF(String html, String targetFileName) throws Exception {

if (StringUtils.isBlank(html)) {

return null;

}

targetFileName = getFileName(targetFileName);

log.info("生成PDF,targetFileName:{}", targetFileName);

String targetFilePath = getTargetFileTempPath(targetFileName);

FileOutputStream outFile = new FileOutputStream(targetFilePath);

ITextRenderer renderer = new ITextRenderer();

renderer.setDocumentFromString(html);

// 解决中文支持问题

log.info("加载字体");

ITextFontResolver fontResolver = renderer.getFontResolver();

fontResolver.addFont(SystemConfig.SourceHanSansCN_Regular_TTF, "SourceHanSansCN", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED, null);

fontResolver.addFont(SystemConfig.FONT_PATH_SONG, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

renderer.layout();

renderer.createPDF(outFile);

log.info("生成PDF,targetFileName:{},生成成功", targetFileName);

return targetFileName;

}

/**

* 渲染文件

*

* @param filePath PDF文件路径

* @param outFilePath PDF文件路径

* @param pdfStamperConfig pdfStamperConfig

* @param pdfWatermarkConfig pdfWatermarkConfig

*/

public void renderLayer(String filePath, String outFilePath, PDFStamperConfig pdfStamperConfig, PDFWatermarkConfig pdfWatermarkConfig) {

log.info("渲染文件,filePath:{},outFilePath:{}", filePath, outFilePath);

InputStream inputStream = null;

try {

filePath = getTargetFileTempPath(filePath);

inputStream = new FileInputStream(filePath);

PdfReader reader = new PdfReader(inputStream);

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(getTargetFileTempPath(outFilePath)));

if (Objects.nonNull(pdfStamperConfig) && pdfStamperConfig.getGenerate()) {

// 印章

log.info("添加印章,pdfStamperConfig:{}", pdfStamperConfig);

stamper(pdfStamperConfig, reader, stamper);

}

if (Objects.nonNull(pdfWatermarkConfig) && pdfWatermarkConfig.getGenerate()) {

// 水印

log.info("添加水印,pdfWatermarkConfig:{}", pdfWatermarkConfig);

watermark(reader, stamper, pdfWatermarkConfig);

}

stamper.close();

reader.close();

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (null != inputStream) {

inputStream.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

/**

* 印章

*

* @param pdfStamperConfig pdfStamperConfig

* @param reader reader

* @param stamper stamper

* @throws IOException IOException

* @throws DocumentException DocumentException

*/

private void stamper(PDFStamperConfig pdfStamperConfig, PdfReader reader, PdfStamper stamper) throws IOException, DocumentException {

Image image;

if (!MyStringUtil.isHttpUrl(pdfStamperConfig.getStamperUrl())) {

// 将项目中的文件copy到服务器本地

String imagePath = pdfStamperConfig.getStamperUrl();

String imageName = imagePath.substring(imagePath.indexOf("/") + 1, imagePath.length());

String localTempPath = systemConfig.getLocalTempPath();

String target = (localTempPath.endsWith(File.separator) ? localTempPath : localTempPath + File.separator) + imageName;

InputStream tempFileInputStream = new ClassPathResource(pdfStamperConfig.getStamperUrl()).getInputStream();

FileUtils.copyInputStreamToFile(tempFileInputStream, new File(target));

image = Image.getInstance(target);

} else {

image = Image.getInstance(pdfStamperConfig.getStamperUrl());

}

PdfReaderContentParser parser = new PdfReaderContentParser(reader);

Document document = new Document();

log.info("A4纸width:{},height:{}", document.getPageSize().getWidth(), document.getPageSize().getHeight());

// // 取所在页和坐标,左下角为起点

// float x = document.getPageSize().getWidth() - 240;

// float y = document.getPageSize().getHeight() - 680;

int pageSize = reader.getNumberOfPages();

Location location = pdfStamperConfig.getLocation();

if (Objects.nonNull(location)) {

Integer page = location.getPage();// -1:全部,0:最后一页,1:首页

if (Objects.nonNull(page)) {

switch (page) {

case -1:

for (int pageNumber = 1; pageNumber <= pageSize; pageNumber++) {

insertImage(pdfStamperConfig, stamper, image, parser, pageSize);

}

break;

case 0:

insertImage(pdfStamperConfig, stamper, image, parser, pageSize);

break;

default:

if (page > 0) {

insertImage(pdfStamperConfig, stamper, image, parser, page);

}

break;

}

}

}

}

/**

* 向指定位置插入图片

*

* @param pdfStamperConfig pdfStamperConfig

* @param stamper stamper

* @param image image

* @param parser parser

* @param pageNumber pageNumber

* @throws IOException IOException

* @throws DocumentException DocumentException

*/

private void insertImage(PDFStamperConfig pdfStamperConfig, PdfStamper stamper, Image image, PdfReaderContentParser parser, int pageNumber)

throws IOException, DocumentException {

float x, y;

Location xy = new Location();

if (StringUtils.isNotBlank(pdfStamperConfig.getLocation().getWord())) {

parser.processContent(pageNumber, new MyTextLocationListener(pdfStamperConfig, xy));

} else {

xy = pdfStamperConfig.getLocation();

}

if (Objects.isNull(xy)) {

return;

}

if (Objects.isNull(xy.getX()) || Objects.isNull(xy.getY())) {

return;

}

x = xy.getX();

y = xy.getY();

if (x < 0 || y < 0) {

return;

}

// 读图片

// 获取操作的页面

PdfContentByte under = stamper.getOverContent(pageNumber);

// 根据域的大小缩放图片

// image.scaleToFit(Objects.isNull(pdfStamperConfig.getFitWidth()) ? GlobalConfig.PDF_STAMPER_DEFAULT_FIT_WIDTH : pdfStamperConfig.getFitWidth(),

// Objects.isNull(pdfStamperConfig.getFitHeight()) ? GlobalConfig.PDF_STAMPER_DEFAULT_FIT_HEIGHT : pdfStamperConfig.getFitHeight());

image.scaleAbsolute(Objects.isNull(pdfStamperConfig.getFitWidth()) ? GlobalConfig.PDF_STAMPER_DEFAULT_FIT_WIDTH : pdfStamperConfig.getFitWidth(),

Objects.isNull(pdfStamperConfig.getFitHeight()) ? GlobalConfig.PDF_STAMPER_DEFAULT_FIT_HEIGHT : pdfStamperConfig.getFitHeight());

// 添加图片

image.setAbsolutePosition(x, y);

under.addImage(image);

}

/**

* 水印

*

* @param reader reader

* @param stamper stamper

* @param pdfWatermarkConfig pdfWatermarkConfig

*/

private void watermark(PdfReader reader, PdfStamper stamper, PDFWatermarkConfig pdfWatermarkConfig) {

if (Objects.isNull(pdfWatermarkConfig) || !pdfWatermarkConfig.getGenerate()) {

return;

}

PdfContentByte under;

// 字体

BaseFont font = PDFFontConfig.FONT_MAP.get(PDFFontConfig.SIM_SUN);

String fontFamily = pdfWatermarkConfig.getFontFamily();

if (StringUtils.isNotBlank(fontFamily) && PDFFontConfig.FONT_MAP.containsKey(fontFamily)) {

font = PDFFontConfig.FONT_MAP.get(fontFamily);

}

// 原pdf文件的总页数

int pageSize = reader.getNumberOfPages();

PdfGState gs = new PdfGState();

// 设置填充字体不透明度为0.1f

gs.setFillOpacity(0.1f);

Document document = new Document();

float documentWidth = document.getPageSize().getWidth(), documentHeight = document.getPageSize().getHeight();

Location location = pdfWatermarkConfig.getLocation();

if (Objects.isNull(location)) {

location = new Location();

}

final float xStart = 0, yStart = 0,

xInterval = Objects.nonNull(location.getXInterval()) ? location.getXInterval() : GlobalConfig.DEFAULT_X_INTERVAL,

yInterval = Objects.nonNull(location.getYInterval()) ? location.getYInterval() : GlobalConfig.DEFAULT_Y_INTERVAL,

rotation = 45,

fontSize = Objects.isNull(pdfWatermarkConfig.getFontSize()) ? GlobalConfig.DEFAULT_FONT_SIZE : pdfWatermarkConfig.getFontSize();

String watermarkWord = pdfWatermarkConfig.getWatermarkWord();

int red = -1, green = -1, blue = -1;

String[] colorArray = pdfWatermarkConfig.getWatermarkColor().split(",");

if (colorArray.length >= 3) {

red = Integer.parseInt(colorArray[0]);

green = Integer.parseInt(colorArray[1]);

blue = Integer.parseInt(colorArray[2]);

}

for (int i = 1; i <= pageSize; i++) {

// 水印在之前文本下

if (Objects.nonNull(location.getOverContent()) && location.getOverContent()) {

under = stamper.getOverContent(i);

} else {

under = stamper.getUnderContent(i);

}

under.beginText();

// 文字水印 颜色

if (red >= 0) {

under.setColorFill(new BaseColor(red, green, blue));

} else {

under.setColorFill(BaseColor.GRAY);

}

// 文字水印 字体及字号

under.setFontAndSize(font, fontSize);

under.setGState(gs);

// 文字水印 起始位置

under.setTextMatrix(xStart, yStart);

if (StringUtils.isNotBlank(watermarkWord)) {

for (float x = xStart; x <= documentWidth + xInterval; x += xInterval) {

for (float y = yStart; y <= documentHeight + yInterval; y += yInterval) {

under.showTextAligned(Element.ALIGN_CENTER, watermarkWord, x, y, rotation);

}

}

}

under.endText();

}

}

/**

* 获取生成的PDF文件本地临时路径

*

* @param targetFileName 目标文件名

* @return 本地临时路径

*/

public String getTargetFileTempPath(String targetFileName) {

String localTempPath = systemConfig.getLocalTempPath();

if (!localTempPath.endsWith(File.separator)) {

localTempPath = localTempPath + File.separator;

}

return localTempPath + targetFileName;

}

private String getFileName(String targetFileName) {

if (StringUtils.isBlank(targetFileName)) {

targetFileName = generatedKey.generatorKey();

}

if (!StringUtils.endsWithIgnoreCase(targetFileName, GlobalConfig.PDF_SUFFIX)) {

targetFileName = targetFileName + GlobalConfig.PDF_SUFFIX;

}

return targetFileName;

}

}

获取指定文字坐标,用来在指定文字上生成印章,主要实现了RenderListener来获取指定文字的坐标。

源码:

package com.lifengdi.file.pdf.listener;

import com.itextpdf.awt.geom.Rectangle2D;

import com.itextpdf.text.pdf.parser.ImageRenderInfo;

import com.itextpdf.text.pdf.parser.RenderListener;

import com.itextpdf.text.pdf.parser.TextRenderInfo;

import com.lifengdi.config.GlobalConfig;

import com.lifengdi.model.pdf.Location;

import com.lifengdi.model.pdf.PDFStamperConfig;

import lombok.extern.slf4j.Slf4j;

import mons.lang3.StringUtils;

import java.util.Objects;

/**

* @author 李锋镝

* @date Create at 15:32 /5/9

*/

@Slf4j

public class MyTextLocationListener implements RenderListener {

private String text;

private PDFStamperConfig pdfStamperConfig;

private Location location;

public MyTextLocationListener(PDFStamperConfig pdfStamperConfig, Location location) {

if (StringUtils.isNotBlank(pdfStamperConfig.getLocation().getWord())) {

this.text = pdfStamperConfig.getLocation().getWord();

}

this.pdfStamperConfig = pdfStamperConfig;

this.location = location;

}

@Override

public void beginTextBlock() {

}

@Override

public void renderText(TextRenderInfo renderInfo) {

String renderInfoText = renderInfo.getText();

if (!StringUtils.isEmpty(renderInfoText) && renderInfoText.contains(text)) {

Rectangle2D.Float base = renderInfo.getBaseline().getBoundingRectange();

float leftX = (float) base.getMinX();

float leftY = (float) base.getMinY() - 1;

float rightX = (float) base.getMaxX();

float rightY = (float) base.getMaxY() + 1;

Rectangle2D.Float rect = new Rectangle2D.Float(leftX, leftY, rightX - leftX, rightY - leftY);

// 当前行长度

int length = renderInfoText.length();

// 单个字符的长度

float wordWidth = rect.width / length;

// 指定字符串首次出现的索引

int i = renderInfoText.indexOf(text);

Float fitWidth = Objects.isNull(pdfStamperConfig.getFitWidth()) ? GlobalConfig.PDF_STAMPER_DEFAULT_FIT_WIDTH : pdfStamperConfig.getFitWidth();

Float fitHeight = Objects.isNull(pdfStamperConfig.getFitHeight()) ? GlobalConfig.PDF_STAMPER_DEFAULT_FIT_HEIGHT : pdfStamperConfig.getFitHeight();

float fitWidthRadius = 0f, fitHeightRadius = 0f;

if (fitWidth > 0) {

fitWidthRadius = fitWidth / 2;

}

if (fitHeight > 0) {

fitHeightRadius = fitHeight / 2;

}

// 偏移量

Float xOffset = Objects.isNull(pdfStamperConfig.getXOffset()) ? 0F : pdfStamperConfig.getXOffset();

Float yOffset = Objects.isNull(pdfStamperConfig.getYOffset()) ? 0F : pdfStamperConfig.getYOffset();

// 设置印章的XY坐标

float x, y;

if (rect.x < 60) {

x = wordWidth * i + fitHeightRadius + xOffset;

} else {

x = rect.x + xOffset;

}

y = rect.y - fitWidthRadius + yOffset;

location.setY(y > 0 ? y : 0);

location.setX(x > 0 ? x : 0);

log.info("text:{}, location:{}", text, location);

}

}

@Override

public void endTextBlock() {

}

@Override

public void renderImage(ImageRenderInfo renderInfo) {

}

}

其他配置类:

package com.lifengdi.model.pdf;

import lombok.Data;

/**

* PDF模板配置

* @author 李锋镝

* @date Create at 11:10 /5/9

*/

@Data

public class PDFTempFile {

/**

* PDF模板文件类型

*/

private String pdfType;

/**

* 模板文件名称

*/

private String templateFileName;

/**

* 模板文件所在父级路径

*/

private String templateFileParentPath;

/**

* 模板文件本地地址

*/

private String templateFileLocalPath;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。