如何用Htmlunit生成网页图片/PDF及WebClient响应渲染
Great question! HtmlUnit itself doesn’t include native tools to render pages directly into images or PDFs, but you can easily pair it with other Java libraries to achieve this—while preserving external images and CSS. Let’s walk through both image and PDF generation using your existing code as a starting point.
We’ll use Flying Saucer’s Java2DRenderer for this task. It can take the XHTML output from HtmlUnit and render it into a buffered image, respecting CSS and external resources.
Step 1: Add Dependencies
First, include these Maven dependencies (adjust versions if needed for your project):
<!-- Flying Saucer core for rendering --> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-core</artifactId> <version>9.1.22</version> </dependency> <!-- Java2D adapter for image output --> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-java2d</artifactId> <version>9.1.22</version> </dependency>
Step 2: Extend Your Code
Modify your existing code to convert the HtmlUnit page to an image:
import org.xhtmlrenderer.java2d.Java2DRenderer; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; public class HtmlUnitToImage { public static void main(String[] args) throws Exception { // Your existing setup WebClient webClient = new WebClient(); webClient.getOptions().setThrowExceptionOnScriptError(false); webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); webClient.getOptions().setJavaScriptEnabled(false); webClient.getOptions().setCssEnabled(true); webClient.getOptions().setDownloadImages(true); Page page = webClient.getPage("http://www.example.com"); // Convert the page to standard XHTML (required by Flying Saucer) String xhtmlContent = page.asXml(); // Create renderer with the page's base URL to resolve relative resources Java2DRenderer renderer = new Java2DRenderer( xhtmlContent, page.getWebResponse().getWebRequest().getUrl().toString() ); // Render the page to a buffered image BufferedImage renderedImage = renderer.getImage(); // Save the image to a file ImageIO.write(renderedImage, "PNG", new File("page-output.png")); // Clean up webClient.close(); } }
How It Works
page.asXml()outputs the fully processed XHTML from HtmlUnit, including all loaded CSS and image references.- The base URL passed to
Java2DRendererensures relative paths (for images/CSS) are resolved correctly, just like a browser would.
For PDF output, we’ll use Flying Saucer’s ITextRenderer (paired with iText for PDF handling). This will preserve all styling and external resources in the final PDF.
Step 1: Add Dependencies
Include these Maven dependencies:
<!-- Flying Saucer PDF renderer --> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.1.22</version> </dependency> <!-- iText PDF library (required by Flying Saucer) --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency>
Step 2: Extend Your Code
Update your code to generate a PDF:
import org.xhtmlrenderer.pdf.ITextRenderer; import java.io.FileOutputStream; import java.io.OutputStream; public class HtmlUnitToPdf { public static void main(String[] args) throws Exception { // Your existing setup WebClient webClient = new WebClient(); webClient.getOptions().setThrowExceptionOnScriptError(false); webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); webClient.getOptions().setJavaScriptEnabled(false); webClient.getOptions().setCssEnabled(true); webClient.getOptions().setDownloadImages(true); Page page = webClient.getPage("http://www.example.com"); // Convert to XHTML String xhtmlContent = page.asXml(); // Initialize PDF renderer ITextRenderer pdfRenderer = new ITextRenderer(); // Set base URL to resolve relative resources pdfRenderer.setDocumentFromString( xhtmlContent, page.getWebResponse().getWebRequest().getUrl().toString() ); pdfRenderer.layout(); // Generate and save the PDF OutputStream outputStream = new FileOutputStream("page-output.pdf"); pdfRenderer.createPDF(outputStream); // Clean up outputStream.close(); webClient.close(); } }
- JavaScript-Dependent Content: If the page relies on JavaScript to render content (e.g., dynamic charts, loaded data), you’ll need to enable JavaScript in HtmlUnit (
webClient.getOptions().setJavaScriptEnabled(true)). You may also need to add a wait time (webClient.waitForBackgroundJavaScript(5000)) to let scripts finish executing. - Cross-Domain Resources: HtmlUnit may block cross-domain resources by default. To fix this, enable cross-domain redirects:
webClient.getOptions().setCrossDomainRedirectEnabled(true). - Dependency Compatibility: Ensure your Flying Saucer and iText versions are compatible. The versions listed above work well together, but check for updates if you run into issues.
内容的提问来源于stack exchange,提问作者Henrique Fernandes Cipriano

