如何在 Java 中使用 wkhtmlpdf 将 HTML 文件转换为 PDF
How to convert an HTML file to PDF using wkhtmlpdf in Java
我想使用 wkhtmltopdf
将 HTML 文件转换为 PDF 文件。 wkhtmltopdf
对我来说是最佳选择,因为它使用 WebKit 呈现 HTML 文件。问题是我想使用 Java 做同样的事情,但 wkhtmltopdf
不提供任何 Java API。
我可以使用 Runtime.exec()
或 ProcessBuilder
从 Java 派生一个新进程,并在该进程中使用 wkhtmtopdf
创建 PDF 输出。但是,由于我正在开发基于 Web 的应用程序,因此不允许在服务器中创建这么多新进程。
有没有其他方法可以使用wkhtmltopdf
?我真的很想使用它,因为它能给我准确的输出。
或者,是否有任何其他开源浏览器引擎提供 Java API 可以像 wkhtmltopdf
一样呈现我的 HTML 页面?
wkhtmltopdf 有一个 C API。然后,您可以使用 JNI 进行 Java 到 C 的通信。
编辑:还有一个 Java 包装器:wkhtmltopdf-wrapper。
请记住,系统 运行 宁你的 Java 代码必须安装 wkhtmltopdf 才能让我在这里说的任何工作......去www.wkhtmltopdf.org 并下载你需要的版本。
我知道这已经过时了,现在您肯定已经明白了,但是如果您不想使用 JNI 或 JNA 来执行此操作,您可以通过系统上的 .exec 调用非常简单地完成.
这里有一个 class 可以完全满足您的需求,而不必为 JNI 或 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
}
}
您必须以某种方式绑定到输入流之一,以便进程到达 运行。这可以是 inputStream 或 errorStream。在这种情况下,因为我只是写入一个文件,所以我继续将 System.err 连接到 wkhtml 进程的 errorStream。
如何只使用流!
如果您希望源 HTML 来自流 and/or 将目标 PDF 写入流,那么您将使用 '-' 用于 "URI" 而不是常规字符串。
示例:wkhtmltopdf - -
或 wkhtmltopdf /Users/Shared/somefile.html -
然后您可以捕获输入和输出流并根据需要进行写入和读取。
如果您只连接到单个流,则不需要使用线程,并且不会出现流无休止地相互等待的情况。
但是,如果您对 HTML 源和 PDF 目标都使用流,那么您必须使用线程才能完成该过程。
注意:请记住,必须刷新并关闭 OutputStream,wkhtmltopdf 才能开始构建 PDF 并流式传输结果!
示例:
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
}
}
当您 运行 在 Web 服务器上进行此操作并希望避免创建临时 HTML 或 PDF 文件时,流非常有用,您可以通过捕获和写入来简单地流回响应到 HTTP 响应流。
希望对大家有所帮助!
试试 htmltopdf-java。它使用由 wkhtmltopdf
生成的本机库,因此您应该期望获得相同的结果并更好地控制流程。
(我是这个库的作者)
我想使用 wkhtmltopdf
将 HTML 文件转换为 PDF 文件。 wkhtmltopdf
对我来说是最佳选择,因为它使用 WebKit 呈现 HTML 文件。问题是我想使用 Java 做同样的事情,但 wkhtmltopdf
不提供任何 Java API。
我可以使用 Runtime.exec()
或 ProcessBuilder
从 Java 派生一个新进程,并在该进程中使用 wkhtmtopdf
创建 PDF 输出。但是,由于我正在开发基于 Web 的应用程序,因此不允许在服务器中创建这么多新进程。
有没有其他方法可以使用wkhtmltopdf
?我真的很想使用它,因为它能给我准确的输出。
或者,是否有任何其他开源浏览器引擎提供 Java API 可以像 wkhtmltopdf
一样呈现我的 HTML 页面?
wkhtmltopdf 有一个 C API。然后,您可以使用 JNI 进行 Java 到 C 的通信。
编辑:还有一个 Java 包装器:wkhtmltopdf-wrapper。
请记住,系统 运行 宁你的 Java 代码必须安装 wkhtmltopdf 才能让我在这里说的任何工作......去www.wkhtmltopdf.org 并下载你需要的版本。
我知道这已经过时了,现在您肯定已经明白了,但是如果您不想使用 JNI 或 JNA 来执行此操作,您可以通过系统上的 .exec 调用非常简单地完成.
这里有一个 class 可以完全满足您的需求,而不必为 JNI 或 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
}
}
您必须以某种方式绑定到输入流之一,以便进程到达 运行。这可以是 inputStream 或 errorStream。在这种情况下,因为我只是写入一个文件,所以我继续将 System.err 连接到 wkhtml 进程的 errorStream。
如何只使用流!
如果您希望源 HTML 来自流 and/or 将目标 PDF 写入流,那么您将使用 '-' 用于 "URI" 而不是常规字符串。
示例:wkhtmltopdf - -
或 wkhtmltopdf /Users/Shared/somefile.html -
然后您可以捕获输入和输出流并根据需要进行写入和读取。
如果您只连接到单个流,则不需要使用线程,并且不会出现流无休止地相互等待的情况。
但是,如果您对 HTML 源和 PDF 目标都使用流,那么您必须使用线程才能完成该过程。
注意:请记住,必须刷新并关闭 OutputStream,wkhtmltopdf 才能开始构建 PDF 并流式传输结果!
示例:
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
}
}
当您 运行 在 Web 服务器上进行此操作并希望避免创建临时 HTML 或 PDF 文件时,流非常有用,您可以通过捕获和写入来简单地流回响应到 HTTP 响应流。
希望对大家有所帮助!
试试 htmltopdf-java。它使用由 wkhtmltopdf
生成的本机库,因此您应该期望获得相同的结果并更好地控制流程。
(我是这个库的作者)