Flying Saucer 方案
Flying Saucer 开源协议的的坑
flying-saucer-core - Core library and Java2D rendering 开源协议LGPL
flying-saucer-pdf - PDF output using OpenPDF (ex. iText 2.x) 开元协议 MPL-2.0/LGPL
flying-saucer-pdf-itext5 - PDF output using iText 5.x (iText 5 is EOL) 开源协议是AGPL不要使用
flying-saucer-pdf-openpdf - not supported anymore (replaced by flying-saucer-pdf)
能用的就只有flying-saucer-core和flying-saucer-pdf 两个组件
实现
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-core</artifactId>
<version>9.1.22</version>
</dependency>
遗留问题:字体一直生效不了,生成的图片字体显示差点意思,没有结合flying-saucer-pdf组件
// 心率报告模板
String htmlString = "<!DOCTYPE html>\n" +
"<html lang=\"zh-CN\">\n" +
" <head>\n" +
" <meta charset=\"UTF-8\" />\n" +
" <title>检测报告</title>\n" +
" <style>\n" +
"@font-face {" +
" font-family: 'STCAIYUN';" +
" src: url('C:\\Windows\\Fonts\\STCAIYUN.TTF');" + // Replace with the path to your custom font file
"}" +
" body {\n" +
" font-family: \"STCAIYUN\", sans-serif;\n" +
" margin: 0;\n" +
" padding: 0;\n" +
" font-size: 14px;\n" +
" color: #333;\n" +
" }\n" +
" .report {\n" +
" width: 80%%;\n" +
" margin: 20px auto;\n" +
" background-color: #fff;\n" +
" padding: 20px;\n" +
" }\n" +
" .report h1 {\n" +
" text-align: center;\n" +
" font-size: 20px;\n" +
" margin-bottom: 10px;\n" +
" }\n" +
" table {\n" +
" width: 100%%;\n" +
" border-collapse: collapse;\n" +
" margin-bottom: 15px;\n" +
" }\n" +
" th,\n" +
" td {\n" +
" padding: 8px 10px;\n" +
" text-align: left;\n" +
" }\n" +
" tr:nth-child(odd) {\n" +
" background-color: transparent;\n" +
" }\n" +
" .status-bad {\n" +
" color: #e54d4d;\n" +
" }\n" +
" .status-good {\n" +
" color: #26b281;\n" +
" }\n" +
" .t1 {\n" +
" border-bottom: 1px solid #ddd;\n" +
" }\n" +
" </style>\n" +
" </head>\n" +
" <body>\n" +
" <div class=\"report\">\n" +
" <h1>检测报告</h1>\n" +
" <table class=\"t1\">\n" +
" <tr>\n" +
" <th>年龄</th>\n" +
" <td>%s岁</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <th>身高</th>\n" +
" <td>%scm</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <th>体重</th>\n" +
" <td>%skg</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <th>日常运动强度</th>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <th>生活习惯</th>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <th>患有疾病</th>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" </table>\n" +
" <table>\n" +
" <tr>\n" +
" <th>检测项目</th>\n" +
" <th>结果值</th>\n" +
" <th>状态</th>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>心率</td>\n" +
" <td>%sbpm</td>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>血氧饱和度</td>\n" +
" <td>%s</td>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>呼吸频率</td>\n" +
" <td>%s次/分钟</td>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>微循环</td>\n" +
" <td>%s</td>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>心率变异性</td>\n" +
" <td>%s</td>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>不规则心律</td>\n" +
" <td>%s次/分钟</td>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>疲劳指数</td>\n" +
" <td>%s</td>\n" +
" <td>%s</td>\n" +
" </tr>\n" +
" </table>\n" +
" </div>\n" +
" </body>\n" +
"</html>\n";
//处理数据
ArrayList<String> fieldValues = new ArrayList<>();
// 获取 HeartRateReport 类的所有字段
Field[] fields = HeartRateReport.class.getDeclaredFields();
for (Field field : fields) {
if ("channelId".equals(field.getName())||"archiveId".equals(field.getName())) {
continue;
}
// 设置字段可访问
field.setAccessible(true);
// 获取字段值并添加到集合中
Object value = field.get(heartRateReport);
fieldValues.add(String.valueOf(value));
}
String text =String.format(htmlString,fieldValues.toArray());
//String text = MessageFormat.format(htmlString, fieldValues);
// 创建 DocumentBuilder 对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
// 使用 DocumentBuilder 将 HTML 字符串解析为 org.w3c.dom.Document 对象
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(text));
Document doc = builder.parse(is);
Java2DRenderer java2DRenderer = new Java2DRenderer(doc, 800, 600);
BufferedImage image = java2DRenderer.getImage();
File outputFile = new File("C:\\\\Users\\\\mjyang6\\\\Desktop\\\\a2.png");
FSImageWriter imageWriter = new FSImageWriter();
imageWriter.setWriteCompressionQuality(1.0f);
imageWriter.write(image, "C:\\\\Users\\\\mjyang6\\\\Desktop\\\\a2.png");
//ImageIO.write(image, "png", outputFile);
/*// 加载本地字体文件
Font customFont = Font.createFont(Font.TRUETYPE_FONT, new File("C:\\Windows\\Fonts\\simhei.ttf"));
// 调整字体大小和样式
customFont = customFont.deriveFont(Font.PLAIN, 10);
Java2DRenderer java2DRenderer = new Java2DRenderer(doc, 800, 600);
BufferedImage image = java2DRenderer.getImage();
Graphics2D graphics = image.createGraphics();
graphics.setFont(customFont);
ImageIO.write(image, "png", new File("C:\\\\Users\\\\mjyang6\\\\Desktop\\\\a3.png"));
graphics.dispose();*/
PDFBox方案
适应性的问题比较难搞,效果可以,但是不好满足根据模板生成pdf的要求,未具体实现
标签:java,image,flying,生成,new,pdf,font,saucer From: https://www.cnblogs.com/edger007/p/18136105