java生成图片和pdf

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的要求,未具体实现

posted @ 2024-04-16 10:26  Edger001  阅读(192)  评论(0)    收藏  举报