生成PDF报表是很多企业系统常见的需求, 有些对外提供报表的系统还需要对生成的pdf文件添加水印, 本文将介绍以上2个问题简单又免费的技术方案 ( 商业收费可见: 最新版ItextPdf )

依赖

免费方案要用到的 第三方依赖有:

thymleaf : 用来生成html, 你也可以换成其他的模板引擎, 如: freemarker

itextpdf 5 : 用来将html渲染成pdf文件

本文的方案基于spring boot开发, 简化了许多thymleaf的配置, 当然你也可以手动配置.

以下是maven依赖,

org.springframework.boot

spring-boot-starter-thymeleaf

com.itextpdf

itextpdf

5.5.11

compile

com.itextpdf

itext-asian

5.2.0

compile

com.itextpdf.tool

xmlworker

5.5.11

复制代码

或Grade依赖 :

implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

implementation 'com.itextpdf:itextpdf:5.5.11'

implementation 'com.itextpdf:itext-asian:5.2.0'

implementation 'com.itextpdf.tool:xmlworker:5.5.11'

复制代码

生成html

html = html模板 + 参数

thymleaf的模板语法与大多数模板引擎的语法都比较类似, 对于前端框架如vue、angular、react的开发者只需要一点点查阅手册就可以迅速上手, 此处是 thymleaf模板语法文档.

spring boot 引入thymleaf的方式非常简单, 后文会提供必要的配置, 下方是使用thymleaf模板引擎生成html的代码片段:

public String generateHtml(String templateName, Map data){

Context ctx = new Context();

ctx.setVariables(data);

return templateEngine.process(templateName, ctx);

}

复制代码

其中: templateEngine是org.thymeleaf.TemplateEngine 实例, 通过依赖注入取得.

templateName 是模板的名字, 与模板文件的名称对应, 模板文件的路径通过下面这段代码片段来配置, 这也是thymleaf所需要的所有配置.

@Configuration

public class ThymeleafConfiguration{

@Bean

public ClassLoaderTemplateResolver emailTemplateResolver(){

ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();

templateResolver.setPrefix("templates/");

templateResolver.setTemplateMode("HTML5");

templateResolver.setSuffix(".html");

templateResolver.setCharacterEncoding("UTF-8");

templateResolver.setOrder(1);

return templateResolver;

}

}

复制代码

这段配置会扫描 /src/main/resources/templates路径下, 后缀为.html的文件作为html模板.

例如: String html = generateHtml("pdf/report", context); 则会将模板文件/src/main/resources/templates/pdf/reprot.html 与context中的数据, 合成html内容.

生成pdf

pdf = render(html)

利用com.itextpdf.text.pdf.PdfWriter 将html 渲染成pdf, 下方的代码片段已经是全部代码.

private File render(String html) throws IOException, DocumentException{

FileOutputStream os = null;

try {

File outputFile = File.createTempFile("temp.pdf");

os = new FileOutputStream(outputFile);

Document document = new Document(PageSize.A4);

PdfWriter pdfWriter = PdfWriter.getInstance(document, os);

pdfWriter.setPageEvent(new Header());

document.setMargins(30, 30, 40, 50);

document.open();

InputStream htmlStream = new ByteArrayInputStream(html.getBytes("UTF-8"));

XMLWorkerHelper.getInstance().parseXHtml(

pdfWriter,

document,

htmlStream,

Charset.forName("UTF-8"),

fontProvider);

document.close();

return outputFile;

} finally {

if (os != null) {

try {

os.close();

} catch (IOException e) { /*ignore*/ }

}

}

}

private FontProvider fontProvider = new FontProvider() {

@Override

public boolean isRegistered(String s){

return false;

}

@Override

public Font getFont(String fontFamily, String charset, boolean arg2, float size, int style, BaseColor color){

BaseFont chinese = null;

try {

chinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

} catch (DocumentException | IOException e) {

e.printStackTrace();

}

return new Font(chinese, size, style, color);

}

};

复制代码

值得注意的地方是, itextpdf对于中文支持不是十分友好, 如果不手动设置中文字体, 渲染出来的中文会变成空白.

上面的代码片段中fontProvider展示了自定义字体的方法.

添加水印

水印PDF = paint(原PDF)

public static File paint(File file) throws IOException, DocumentException{

PdfReader reader = new PdfReader(file.getPath());

File dest = File.createTempFile("withMask", "pdf", file.getParentFile());

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));

int n = reader.getNumberOfPages();

stamper.setRotateContents(false);

// text watermark

BaseFont chinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);

Font f = new Font(chinese, 80);

Font fontHeader = new Font(chinese, 10);

// transparency

PdfGState gs1 = new PdfGState();

gs1.setFillOpacity(0.1f);

// properties

PdfContentByte over;

Rectangle pagesize;

float x, y;

// loop over every page

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

pagesize = reader.getPageSize(i);

over = stamper.getOverContent(i);

over.saveState();

over.setGState(gs1);

x = (pagesize.getLeft() + pagesize.getRight()) / 2 - 25;

y = (pagesize.getTop() + pagesize.getBottom()) / 2 + 60;

Phrase p = new Phrase("水印文字", f);

ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, x, y, 45);

over.restoreState();

}

stamper.close();

reader.close();

return dest;

}

复制代码

java 生成水印,Java 用html模板生成 Pdf 加水印相关推荐

  1. java pdf水印排布问题_java 实现 PDF 加水印功能

    使用java代码实现给PDF加水印的功能 首先导入所需要的依赖 com.itextpdf itextpdf 5.5.11 com.itextpdf itext-asian 5.2.0 java 代码实 ...

  2. (Java)word转pdf(aspose),pdf加水印(itextpdf),并支持POI模板(包括checkbox)导出

    目录 1.引入jar包 2.pdf处理工具类 3.poi模板导出工具类 4.测试类 5.模板 6.最终效果 1.引入jar包 2.pdf处理工具类 import com.aspose.cells.Pd ...

  3. Java实现Excel和word转pdf加水印,复制及可用

    Java实现Excel和word转pdf加水印,复制及可用 时隔大半年,之前朋友,今天突然找我说,他们有个需求要做这东西.想起来之前自己照着官方文档写,也走了不少坑.今天就索性写个,也为了方便以后使用 ...

  4. java如何给pdf加水印_java pdf加水印的方法

    本文实例为大家分享了java pdf加水印的具体代码,供大家参考,具体内容如下 引入依赖 com.itextpdf.tool xmlworker 5.5.10 com.itextpdf itextpd ...

  5. java使用2种方法操作liberoffice把word转pdf,pdf加水印,java远程调用Linux执行命令

    文章目录 libreoffice下载地址 安装 (第一种) java调用 (第二种 推荐) java调用Linux命令转pdf java远程连接Linux执行命令(少数情况) linux安装windo ...

  6. Springboot使用itext及documents4j操作pdf(word转pdf、pdf加水印(文字或图片,可指定位置)、pdf加密(打开密码,编辑密码))

    pom.xml引入 <!-- pdf文档生成 --><dependency><groupId>com.documents4j</groupId>< ...

  7. XDOC Office Server 发布 1.1.0 版本,支持 PDF 加水印

    XDOC Office Server 是一个 JavaEE 服务,用于将 Office 文档转换为 PDF,格式兼容性好. 版本更新 支持 &_watermark 参数,对生成的 PDF 加水 ...

  8. itextPDF5.5.13 pdf加水印的权限控制

    1.我们的需求需要对pdf加水印,其中有加密的和未加密的, 操作过程中发现 有的虽然加密了 但是符合PDFReader的五种加密算法,就可以成功破解加水印,还有一些就会抛出一些异常 第一种报错:com ...

  9. PDF转换图片,图片的切割,图片转换PDF以及PDF加水印等记录贴

    PDF转变为图片: 把图片进行切割: 把图片转变回PDF: 为PDF加水印文字: 为PDF加水印图片. 1,PDF转变为图片 /*** @author dalin*将PDF格式的文件转换成png文件* ...

  10. 怎么给pdf加水印,pdf加水印步骤

    怎么给pdf加水印?有时候位置方式别人随意使用pdf文件里面的内容,我们需要给做好的pdf文件添加水印,这样可以起到一定的保护作用,那么怎么给pdf文件添加水印呢?有的小伙伴肯定会说,用专业的pdf编 ...

最新文章

  1. POJ 3069 Saruman's Army(贪心)
  2. gridview中如果文字太多指点要显示的文字
  3. Nacos配置中心介绍
  4. 每个产品经理都应该知道的机器学习术语
  5. js php调用webservice,php调用web services两种方法soap和curl
  6. 请问在JAVA编程中什么叫耦合?什么又叫解藕? 悬赏分:0 - 解决时间:2008-3-8 12:55...
  7. 微信小程序之底部弹框预约插件
  8. [rsync] linux rsync 安装
  9. gflags的使用实例(转载)
  10. 数学建模时序数据分析——趋势性检验和平稳性检验
  11. C++卡常数之内存优化
  12. 上天入地影无踪:十大超级老牌黑客
  13. 控制/ 状态寄存器(RCC_CSR) 复位
  14. 将视频文件旋转90°的方法
  15. wordpress不同角色显示不同的菜单栏
  16. 梦幻星空html,HTML5特效展示,梦幻星空
  17. Python3入门教程::Excel 基础操作(下)
  18. 网口灯电路——反相器
  19. ThinkPad T460s BIOS设置实现U盘启动
  20. 景联文科技提供智能手表健康监测数据采集服务,涵盖血压血氧心率睡眠数据

热门文章

  1. SQL Server 查询性能优化——覆盖索引(二)
  2. pandas(二) -- Dataframe创建及索引
  3. java 面向对象的特性 抽象_java面向对象的四个特性
  4. Longest Substring Without Repeating Characters
  5. 一篇文章教你学会Java泛型
  6. linux shell数组定义、元素获取及其长度获取
  7. docker add-host hostAliases配置/etc/hosts
  8. linux vscode配置HBuilderX雅蓝主题
  9. 地图上的三国(一口气看完15幅地图)
  10. Mac brew安装maven