Hướng dẫn wkhtmltopdf java - wkhtmltopdf java

Hãy nhớ rằng hệ thống chạy mã Java của bạn phải cài đặt wkhtmltopdf cho bất cứ điều gì tôi đang nói ở đây để hoạt động ... Truy cập www.wkhtmltopdf.org và tải xuống phiên bản bạn cần.

Tôi biết điều này đã cũ và bây giờ bạn chắc chắn đã tìm ra điều này, nhưng nếu bạn không muốn sử dụng JNI hoặc JNA để làm điều này, bạn có thể thực hiện nó khá đơn giản thông qua các cuộc gọi .Exec trên hệ thống của bạn.

Dưới đây là một lớp thực hiện chính xác những gì bạn muốn mà không cần phải làm phiền với JNI hoặc JNA:

public class MegaSimplePdfGenerator {

    public void makeAPdf() throws InterruptedException, IOException {
        Process wkhtml; // Create uninitialized process
        String command = "wkhtmltopdf http://www.google.com /Users/Shared/output.pdf"; // Desired command

        wkhtml = Runtime.getRuntime().exec(command); // Start process
        IOUtils.copy(wkhtml.getErrorStream(), System.err); // Print output to console

        wkhtml.waitFor(); // Allow process to run
    }
}

Bạn phải bằng cách nào đó liên kết với một trong các luồng đầu vào để quá trình chạy. Đó có thể là đầu vào hoặc lỗi. Trong trường hợp này vì tôi vừa viết vào một tập tin, tôi đã đi trước và chỉ kết nối hệ thống.err với các lỗi từ quy trình WKHTML.

Làm thế nào để chỉ sử dụng các luồng!

Nếu bạn muốn nguồn HTML đến từ luồng và/hoặc PDF đích sẽ được ghi vào luồng thì bạn sẽ sử dụng '-' cho "URI" thay vì chuỗi thông thường.'-' for the "URI" instead of a regular string.

Ví dụ: wkhtmltopdf - - hoặc wkhtmltopdf /Users/Shared/somefile.html -

Sau đó, bạn có thể nắm bắt các luồng đầu vào và đầu ra và viết và đọc khi cần thiết.

Nếu bạn chỉ kết nối với một luồng thì bạn không cần sử dụng các luồng và bạn sẽ không nhận được một kịch bản trong đó các luồng đang chờ đợi nhau vô tận.

Tuy nhiên, nếu bạn đang sử dụng một luồng cho cả nguồn HTML và đích PDF, thì bạn phải sử dụng các luồng để quá trình hoàn thành.

Lưu ý: Hãy nhớ rằng OutputStream phải được xóa và đóng cho wkhtmltopdf để bắt đầu xây dựng pdf và phát trực tuyến kết quả!

Thí dụ:

public class StreamBasedPdfGenerator {
  public void makeAPdfWithStreams() throws InterruptedException, IOException {
        Process wkhtml; // Create uninitialized process

        // Start by setting up file streams
        File destinationFile = new File("/Users/Shared/output.pdf");
        File sourceFile = new File("/Users/Shared/pdfPrintExample.html");

        FileInputStream fis = new FileInputStream(sourceFile);
        FileOutputStream fos = new FileOutputStream(destinationFile);

        String command = "wkhtmltopdf - -"; // Desired command

        wkhtml = Runtime.getRuntime().exec(command); // Start process

        Thread errThread = new Thread(() -> {
            try {
                IOUtils.copy(wkhtml.getErrorStream(), System.err);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        Thread htmlReadThread = new Thread(() -> {
            try {
                IOUtils.copy(fis, wkhtml.getOutputStream());
                wkhtml.getOutputStream().flush();
                wkhtml.getOutputStream().close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        Thread pdfWriteThread = new Thread(() -> {
            try {
                IOUtils.copy(wkhtml.getInputStream(), fos);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });

        // Do NOT use Run... it should be clear why, you want them to all be going at the same time.
        errThread.start();
        pdfWriteThread.start();
        htmlReadThread.start();

         // Connect HTML Source Stream to wkhtmltopdf
         // Connect PDF Source Stream from wkhtmltopdf to the Destination file steam

        wkhtml.waitFor(); // Allow process to run
    }
}

Các luồng rất tốt khi bạn đang chạy điều này trên máy chủ web và muốn tránh tạo các tệp HTML hoặc PDF tạm thời, bạn chỉ cần truyền phát lại phản hồi bằng cách chụp và ghi vào luồng phản hồi HTTP.

Tôi hi vọng nó sẽ giúp ích cho mọi người!

quá trình.waitfor ();

bắt (ngoại lệ) { byte[] getPdf(String html) {
log.Error ("Ngoại lệ ném trong khi chuyển đổi sang PDF:" + E);[] results = null;
returnNull; {
trả lại;
}[] command = {"/usr/local/bin/wkhtmltopdf", "-", "-"};
Tệp này chứa văn bản unicode hai chiều có thể được giải thích hoặc biên dịch khác với những gì xuất hiện dưới đây. Để xem xét, hãy mở tệp trong một trình soạn thảo cho thấy các ký tự Unicode ẩn. Tìm hiểu thêm về các ký tự unicode hai chiều builder = new ProcessBuilder(command);
publicByte [] getPdf (StringHtml) {
byte [] kết quả = null;.redirectErrorStream(false);
thử { process = builder.start();
// Để đường ống vào và ra, chúng ta cần một cuộc tranh luận riêng cho điều này vì một số lý do (BufferedOutputStream stdin = new BufferedOutputStream(process.getOutputStream())) {
Chuỗi [] lệnh = {"/usr/local/bin/wkhtmltopdf", "-", "-"};.write(html.getBytes());
}
outputStream.write (x);(BufferedInputStream stdout = new BufferedInputStream(process.getInputStream()); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ) {
kết quả = outputStream.tobyteArray ();
quá trình.waitfor ();
bắt (ngoại lệ) {
log.Error ("Ngoại lệ ném trong khi chuyển đổi sang PDF:" + E);
returnNull; (true) {
intx = stdout.read (); x = stdout.read();
if (x == -1) { (x == -1) {
phá vỡ;;
}
outputStream.write (x);.write(x);
}
outputStream.write (x); = outputStream.toByteArray();
kết quả = outputStream.tobyteArray ();.waitFor();
}
}
outputStream.write (x);(Exception e) {
kết quả = outputStream.tobyteArray ();.error("Exception thrown while converting to pdf: " + e);
quá trình.waitfor (); null;
}
outputStream.write (x); results;
kết quả = outputStream.tobyteArray ();