Wkhtmltopdf ví dụ java

Các ứng dụng thường xuyên được yêu cầu để tạo hóa đơn, báo cáo, thẻ ID, v.v. ở định dạng PDF. Có các thư viện và công cụ Java mà các nhà phát triển có thể sử dụng để tạo các tệp PDF, bao gồm cả JasperReports phổ biến. Mặc dù phức tạp, nhưng việc sử dụng các chương trình này có thể phức tạp vì chúng hỗ trợ nhiều loại tài liệu

Bài viết này giới thiệu một công cụ đơn giản hơn, tiện ích mã nguồn mở wkhtmltopdf. Tôi sẽ chỉ cho bạn cách sử dụng wkhtmltopdf để giải quyết một tình huống phổ biến. Bạn có một biểu mẫu HTML, được tham số hóa để chấp nhận dữ liệu đầu vào và bạn cần tạo tệp PDF từ dữ liệu trong biểu mẫu đó. Bạn sẽ tìm hiểu cách thiết lập dữ liệu của mình và thực hiện cuộc gọi đến tiện ích wkhtmltopdf từ ứng dụng web Spring Boot. Chúng tôi sẽ sử dụng Universal Base Image (UBI) 8 của Red Hat làm hình ảnh cơ sở để đơn giản hóa việc xây dựng ứng dụng, sau đó triển khai hình ảnh cuối cùng vào Red Hat Openshift 4

Ghi chú. Bạn có thể tìm mã cho ví dụ trong kho lưu trữ GitHub của tôi

Cấu hình sử dụng Maven

Hãy bắt đầu với một tệp Maven. Tôi đang sử dụng hóa đơn vật liệu Snowdrop (BOM) trên tệp mô hình đối tượng dự án Maven (POM) của mình thay vì phiên bản cộng đồng của Spring Boot

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.edw</groupId>
    <artifactId>SpringBootAndPdf</artifactId>
    <version>1.0-SNAPSHOT</version>

    <repositories>
        <repository>
            <id>redhat-early-access</id>
            <name>Red Hat Early Access Repository</name>
            <url>https://maven.repository.redhat.com/earlyaccess/all/</url>
        </repository>
        <repository>
            <id>redhat-ga</id>
            <name>Red Hat GA Repository</name>
            <url>https://maven.repository.redhat.com/ga/</url>
        </repository>
    </repositories>


    <pluginRepositories>
        <pluginRepository>
            <id>redhat-early-access</id>
            <name>Red Hat Early Access Repository</name>
            <url>https://maven.repository.redhat.com/earlyaccess/all/</url>
        </pluginRepository>
        <pluginRepository>
            <id>redhat-ga</id>
            <name>Red Hat GA Repository</name>
            <url>https://maven.repository.redhat.com/ga/</url>
        </pluginRepository>
    </pluginRepositories>

    <properties>
        <snowdrop-bom.version>2.4.9.Final-redhat-00001</snowdrop-bom.version>
        <spring-boot.version>2.1.4.RELEASE-redhat-00001</spring-boot.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>dev.snowdrop</groupId>
                <artifactId>snowdrop-dependencies</artifactId>
                <version>${snowdrop-bom.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>


    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.edw.Main</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Chương trình khởi động mùa xuân

Lớp chính của chúng tôi trong Java là

package com.edw;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

Lớp

package com.edw;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
0 sau đây hiển thị một tệp PDF được tạo. Một trong những nhiệm vụ quan trọng nhất của lớp là hiển thị PDF chính xác trong trình duyệt; . Một nhiệm vụ quan trọng khác là gọi một quy trình bên ngoài chạy wkhtmltopdf để kích hoạt chuyển đổi từ HTML sang PDF

package com.edw.controllers;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.UUID;

@Controller
public class ReportController {

    @GetMapping(
            value = "/generate-report",
            produces = MediaType.APPLICATION_PDF_VALUE
    )
    public @ResponseBody byte[] generateReport(@RequestParam(value = "name") String name,
                                               @RequestParam(value = "address") String address) throws Exception {
        String uuid = UUID.randomUUID().toString();
        Path pathHtml = Paths.get("/tmp/" + uuid + ".html");
        Path pathPdf = Paths.get("/tmp/" + uuid + ".pdf");

        try {
            // read the template and fill the data
            String htmlContent = new Scanner(getClass().getClassLoader().getResourceAsStream("template.html"), "UTF-8")
                                    .useDelimiter("\\A")
                                    .next();
            htmlContent = htmlContent.replace("$name", name)
                                        .replace("$address", address);

            // write to html
            Files.write(pathHtml, htmlContent.getBytes());

            // convert html to pdf
            Process generateToPdf = Runtime.getRuntime().exec("wkhtmltopdf " + pathHtml.toString() + " " + pathPdf.toString() );
            generateToPdf.waitFor();

            // deliver pdf
            return Files.readAllBytes(pathPdf);

        } finally {
            // delete temp files
            Files.delete(pathHtml);
            Files.delete(pathPdf);
        }
    }
}

Định dạng dữ liệu HTML

Mẫu HTML sau đây tạo một báo cáo với dữ liệu đầu vào bao gồm tên (tham số

package com.edw;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
4) và địa chỉ (tham số
package com.edw;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
5)

________số 8_______

Cài đặt chương trình wkhtmltopdf

Phần tiếp theo này là nơi phép màu xảy ra. Trước tiên, bạn cần tải xuống wkhtmltopdf từ GitHub và giải nén chương trình. Sau đó, bạn có thể tạo thư mục

package com.edw;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
7 trong dự án Java của mình và sao chép wkhtmltopdf vào thư mục của ứng dụng từ thư mục
package com.edw;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
9

$ wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz

$ tar -xf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz

$ mkdir /code/wkhtml

$ cp wkhtmltox/bin/wkhtmltopdf /code/wkhtml/

Cấu trúc thư mục kết quả trông giống như

+--- .gitignore
+--- Dockerfile
+--- pom.xml
+--- src
|   +--- main
|   |   +--- java
|   |   |   +--- com
|   |   |   |   +--- edw
|   |   |   |   |   +--- controllers
|   |   |   |   |   |   +--- HelloWorldController.java
|   |   |   |   |   |   +--- ReportController.java
|   |   |   |   |   +--- Main.java
|   |   +--- resources
|   |   |   +--- application.properties
|   |   |   +--- template.html
|   +--- test
|   |   +--- java
+--- wkhtml
|   +--- wkhtmltopdf

xây dựng hình ảnh

Dockerfile sau đây sử dụng UBI 8 làm hình ảnh cơ sở

FROM registry.access.redhat.com/ubi8/openjdk-11-runtime:1.10

USER root

ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' TZ='Asia/Jakarta'

RUN microdnf update && \
    microdnf install tzdata libXrender libXext fontconfig  && \
    ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && \
    microdnf clean all

COPY wkhtml/wkhtmltopdf /usr/local/bin/

EXPOSE 8080
USER 185

COPY target/app.jar /deployments/app.jar
ENTRYPOINT [ "java", "-jar", "/deployments/app.jar" ]

Bây giờ, xây dựng hình ảnh của bạn và chạy nó

$ docker build -t springboot-and-pdf . 

$ docker run -p 8080:8080  springboot-and-pdf

Trong trình duyệt của bạn, hãy nhập URL

package com.edw.controllers;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.UUID;

@Controller
public class ReportController {

    @GetMapping(
            value = "/generate-report",
            produces = MediaType.APPLICATION_PDF_VALUE
    )
    public @ResponseBody byte[] generateReport(@RequestParam(value = "name") String name,
                                               @RequestParam(value = "address") String address) throws Exception {
        String uuid = UUID.randomUUID().toString();
        Path pathHtml = Paths.get("/tmp/" + uuid + ".html");
        Path pathPdf = Paths.get("/tmp/" + uuid + ".pdf");

        try {
            // read the template and fill the data
            String htmlContent = new Scanner(getClass().getClassLoader().getResourceAsStream("template.html"), "UTF-8")
                                    .useDelimiter("\\A")
                                    .next();
            htmlContent = htmlContent.replace("$name", name)
                                        .replace("$address", address);

            // write to html
            Files.write(pathHtml, htmlContent.getBytes());

            // convert html to pdf
            Process generateToPdf = Runtime.getRuntime().exec("wkhtmltopdf " + pathHtml.toString() + " " + pathPdf.toString() );
            generateToPdf.waitFor();

            // deliver pdf
            return Files.readAllBytes(pathPdf);

        } finally {
            // delete temp files
            Files.delete(pathHtml);
            Files.delete(pathPdf);
        }
    }
}
0 với tên và địa chỉ làm tham số, và bạn sẽ có một tệp PDF sẵn sàng để tải xuống và in, như thể hiện trong Hình 1

Wkhtmltopdf ví dụ java

Hình 1. Ứng dụng Spring Boot tạo báo cáo PDF từ dữ liệu trong mẫu HTML

Phần kết luận

Quy trình hợp lý hóa được hiển thị trong ví dụ này rất hữu ích trong nhiều tình huống mà bạn muốn tạo báo cáo có dữ liệu dạng bảng hoặc PDF có cấu trúc khác dựa trên dữ liệu đầu vào. Vui lòng để lại nhận xét về bài viết này để thảo luận về nơi bạn có thể sử dụng phương pháp này và bất kỳ câu hỏi nào bạn có thể có

Làm cách nào để chuyển đổi HTML sang PDF trong Java?

Mẫu mã Java sau đây cho biết cách chuyển đổi tài liệu HTML thành PDF. .
Tạo một thể hiện của lớp HtmlLoadOptions
Khởi tạo đối tượng Tài liệu
Lưu tài liệu PDF đầu ra bằng cách gọi Tài liệu. phương thức lưu (Chuỗi)

Gói Wkhtmltopdf là gì?

wkhtmltopdf là công cụ dòng lệnh nguồn mở (LGPLv3) để kết xuất HTML thành PDF bằng công cụ kết xuất Qt WebKit .

Wkhtmltopdf Linux là gì?

Đó là gì? . Chúng chạy hoàn toàn "không đầu" và không yêu cầu dịch vụ hiển thị hoặc hiển thị. Ngoài ra còn có một thư viện C, nếu bạn thích loại đó. open source (LGPLv3) command line tools to render HTML into PDF and various image formats using the Qt WebKit rendering engine. These run entirely "headless" and do not require a display or display service. There is also a C library, if you're into that kind of thing.