java将数据库数据转换成word文档并且生成pdf文件最后转换成对应的图片

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/PSY_God/article/details/82021573

目的:将数据转换成word图片的方式展现给用户

工具:openoffice +java代码 +数据库,其中openoffice有windows版本的和Linux版本的。

其中openoffice的下载地址为:链接:https://pan.baidu.com/s/1Y5Ra3TfNCcvVX1bF-29hjw 密码:44ms

openoffice的安装及启动不在描述:网上自行百度。

下面主要是目的实现的步骤。

第一步:创建openoffice的连接池,使用linkedlist实现。简单的连接池,避免过多的消耗资源!

依赖的jar如下所以,部分jar无法下载,可以本地install 链接:https://pan.baidu.com/s/1wa65hYuxJ8wbIDETvuGDZQ 密码:pamx

 <!--word转pdf以及pdf转图片使用的jar-->
        <dependency>
            <groupId>wisemax</groupId>
            <artifactId>jodconverter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>ridl</artifactId>
            <version>3.2.1</version>
        </dependency>

        <dependency>
            <groupId>xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.1.3</version>
        </dependency>

        <dependency>
            <groupId>commons-cli</groupId>
            <artifactId>commons-cli</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
        </dependency>


        <dependency>
            <groupId>com.artofsolving</groupId>
            <artifactId>jodconverter</artifactId>
            <version>2.2.1</version>
        </dependency>

        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>jurt</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>juh</artifactId>
            <version>3.0.1</version>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>org.slf4j</groupId>-->
            <!--<artifactId>slf4j-jdk14</artifactId>-->
            <!--<version>1.5.6</version>-->
        <!--</dependency>-->
        <dependency>
            <groupId>org.icepdf</groupId>
            <artifactId>icepdf-core</artifactId>
            <version>4.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.openoffice</groupId>
            <artifactId>unoil</artifactId>
            <version>3.2.1</version>
        </dependency>

创建连接openoffice的类,模仿连接池的效果。

public class OpenSource {

    private String url = "127.0.0.1";
    private int port = 8100;
    private static int initCount = 10;//初始化连接数
    private static int maxCount = 15;//最大连接数
    private static int currentCount = 10;//当前连接数

    private static LinkedList<OpenOfficeConnection> connectionsPoll = new LinkedList<OpenOfficeConnection>();

    public OpenSource() {
        try {
            for (int i = 0; i <= initCount; i++) {//初始化生成10个数据库连接
                connectionsPoll.addLast(this.createConnection());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private OpenOfficeConnection createConnection() throws Exception {
        return new SocketOpenOfficeConnection(url, port);
    }

    public void free(OpenOfficeConnection conn) {

        connectionsPoll.addLast(conn);//将连接放回连接池
        System.out.println("连接池的大小为"+connectionsPoll.size());
    }

    public OpenOfficeConnection getConnection() throws Exception {
        synchronized (connectionsPoll) {//多线程并发处理
            if (connectionsPoll.size() > 0) {
                return connectionsPoll.removeFirst();
            } else if (currentCount < maxCount) {
                //未超过最大连接数,则新建连接
                OpenOfficeConnection conn = createConnection();
                connectionsPoll.add(conn);
                currentCount++;
                return conn;
            } else {
                throw new RuntimeException("连接已经用完");
            }
        }
    }

}

再创建一个工具类

public class OpenOfficeUtil {
    private static OpenSource openOfficeSource = null;

    public OpenOfficeUtil() {

    }

    static {
        try {
            openOfficeSource = new OpenSource();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static OpenOfficeConnection getConnection() throws Exception {
        return openOfficeSource.getConnection();
    }

    public static void free(OpenOfficeConnection conn) {
        openOfficeSource.free(conn);
    }

    private static int office2PDF(String sourceFile, String destFile, OpenOfficeConnection connection) {

        try {
            File inputFile = new File(sourceFile);
            if (!inputFile.exists()) {
                return -1;// 找不到源文件, 则返回-1
            }
            // 如果目标路径不存在, 则新建该路径
            File outputFile = new File(destFile);
            if (!outputFile.getParentFile().exists()) {
                outputFile.getParentFile().mkdirs();
            }
            connection.connect();
            DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
            converter.convert(inputFile, outputFile);
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            free(connection);
        }
        return 1;
    }
}

第二步:将数据转换成对应的模板信息。我利用的是github上的开源项目Word模板引擎 https://github.com/Sayi/poi-tl 

具体的步骤和生成文档的方法,里面有很详细的介绍。

下面是我的模板样式:

其中带有{{xx}}为动态生成的数据。后台提供数据即可将数据写入到对应的变量中去。

第三步:生成数据到word文档

①:准备一个如上图所示的模板或者自己定义一个模板,将需要动态生成的数据用{{xx}}进行占位。

  //根据word模板和相关数据生成word文档
    private static String dataToWord(String templatePath) throws Exception {
        //String templatePath = "D:\\worddata\\picc.docx";
        XWPFTemplate template = XWPFTemplate.compile(templatePath).render(new HashMap<String, Object>() {{
            put("caseNo", "订单信息");
            put("info", "案件信息");
            put("baoxian", "☑ 能繁母猪 □ 育肥猪");
            put("baoxian", "今天");
        }});

        String filePath = "";
        FileOutputStream out = new FileOutputStream("D:\\worddata\\out_template11.docx");
        template.write(out);
        out.flush();
        out.close();
        template.close();//多线程下是否需要close掉
        return filePath;

    }

如上代码便是将数据生成word的方法。输出路径为D:\\worddata\\out_template11.docx

其中map中put的key 是模板中的占位符变量。value是对应的值。

第四步:将word转换成pdf,此时要用到了openoffice工具。检查工具是否开启。

 private static String officeToPdf(String sourceFile, String outPdfPath, String caseNo) throws Exception {
        log.info("生成的PDF的路径为:{}", outPdfPath);
        OpenOfficeConnection connection;
        File inputFile = new File(sourceFile + File.separator + caseNo + ".docx");
        if (!inputFile.exists()) {
            return null;// 找不到源文件, 则返回-1
        }
        // 如果目标路径不存在, 则新建该路径
        File outputFile = new File(outPdfPath + File.separator + caseNo + ".pdf");
        if (!outputFile.getParentFile().exists()) {
            outputFile.getParentFile().mkdirs();
        }
        //连接虚拟机上的openOffice
        connection = OpenOfficeUtil.getConnection();
        connection.connect();
        // convert
        DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
        converter.convert(inputFile, outputFile);
        connection.disconnect();
        //释放连接
        OpenOfficeUtil.free(connection);
        return outPdfPath + caseNo + ".pdf";
    }

第五步:将pdf转成图片,图片的格式可以是png 或者jpg,图片的名字自定义。并且将下载的url返回

 private String pdfToPicture(String pdfPath, String outPath, String caseNo) throws Exception {
        String outImagePath = "";
        Document document = new Document();
        document.setFile(pdfPath);
        //缩放比例
        float scale = 2f;
        //旋转角度
        float rotation = 0f;

        synchronized (this) {
            for (int i = 0; i < document.getNumberOfPages(); i++) {
                BufferedImage image = (BufferedImage)
                        document.getPageImage(i, GraphicsRenderingHints.SCREEN, org.icepdf.core.pobjects.Page.BOUNDARY_CROPBOX, rotation, scale);
                RenderedImage rendImage = image;
                try {
                    String imgName = i + ".png";
                    System.out.println(imgName);
                    File file = new File(outPath + caseNo + imgName);
                    if (1 == i) {
                        outImagePath = outPath + imgName;
                    }
                    ImageIO.write(rendImage, "png", file);
                } catch (IOException e) {
                    log.error("PDF转成图片错误信息为:{}", e.getMessage());
                }
                image.flush();
            }
        }
        document.dispose();
        return outImagePath;
    }

生成的图片部分

具体的位置可以进行调整。生成的文字样式可以根据github上的word模板引擎进行修改。里面有很详细的介绍。

提醒建议:

:openoffice的安装,网上百度都有,很简单的,仔细阅读github上的开源项目。

:生成word的模板是自己定义的,文字的位置加粗斜体下划线等由POI-tl提供,类似于freemaker。但是我觉得比freemaker好用些。

:生成的word是一页,但是pdf可能是两页,最后转换图片是根据pdf的页数进行转换的,反正最后都是会转换的。

:最后生成的图片url可以根据自身的需求进行修改。

:jar包可能缺乏,博主的jar是刚好的,如果有冲突或者缺少,大家可以搜一下资料进行修改。

欢迎大家提出问题。

猜你喜欢

转载自blog.csdn.net/PSY_God/article/details/82021573