java 生成水印,Java 用html模板生成 Pdf 加水印
生成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 加水印的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab基数排序,c语言 数据结构
- 下一篇: matlab cameraman,cam