欢迎光临
我们一直在努力

java根据模板生成word,java代码生成模板

生成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 美国高防vps 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;

}

复制代码

10480918

赞(0)
【声明】:本博客不参与任何交易,也非中介,仅记录个人感兴趣的主机测评结果和优惠活动,内容均不作直接、间接、法定、约定的保证。访问本博客请务必遵守有关互联网的相关法律、规定与规则。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。