[英]Preprocessing HTML CSS JS for iText
我正在嘗試使用Java代碼中嵌入的iText將使用HTML / CSS / JS構建的網頁轉換為PDF。 但是,iText通知我們,盡管pdfHTML支持CSS,但它不支持JS。 他們建議使用預處理器來“運行”頁面中的Javascript並獲取原始HTML。
沒有Javascript,iText可以很好地生成PDF。 但是,我們需要能夠將來自服務調用的數據注入HTML。 我使用JQuery完成此任務。 我們還調用並使用FusionCharts API渲染一些圖表。 這些也將一直工作到PDF生成為止。
有人知道這樣的事嗎? 同樣,還需要能夠從我們的Java后端調用它。
謝謝!
有幾種評估HTML + CSS + JS頁面上的JS代碼的方法。 為此,我們需要一個類似瀏覽器的瀏覽器(或瀏覽器本身),因為使用DOM操作評估JS正是瀏覽器在呈現頁面之前必須要做的。
使用HtmlUnit- “ Java程序的GUI更少瀏覽器”。
首先,我們需要添加依賴項(例如通過Maven):
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.32</version>
</dependency>
然后,打開頁面,等待JS完成其工作並將頁面源提供給iText pdfHTML:
WebClient webClient = new WebClient();
// You might need this configuration if HtmlUnit fails without it
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.waitForBackgroundJavaScript(10 * 1000);
HtmlPage page = webClient.getPage(url);
String xml = page.asXml();
ConverterProperties properties = new ConverterProperties().setBaseUri(url);
HtmlConverter.convertToPdf(source, new PdfWriter("result.pdf"), properties);
HtmlUnit不完全支持JS,因此在評估JS代碼時可能會引發錯誤。 因此,您可能想抑制它們(我已在代碼示例中添加了此配置和對此的注釋)。 當然,您的結果可能看起來不正確。 但這是純Java解決方案。
向我們每天使用的現實世界瀏覽器尋求幫助
我們每天使用的瀏覽器(Chrome,Firefox,Safari等)都具有JS評估的最佳支持。 您可以通過使用Selenium Web自動化工具來使用瀏覽器引擎。 我們要做的是在瀏覽器中打開一個頁面,等待頁面加載,然后使用HTML-> PDF轉換源。 我的示例適用於Chrome瀏覽器,但對於其他瀏覽器,您也可以采用類似的方法。 首先,您需要下載 Chrome驅動程序並將其解壓縮到系統中的某個位置。
然后添加以下Maven依賴項:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.14.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.14.0</version>
</dependency>
現在,我們必須編寫一些代碼,類似於第一個選項:
System.setProperty("webdriver.chrome.driver", "C:\\path\\to\\chromedriver.exe");
ChromeDriver driver = new ChromeDriver();
driver.get(url);
new WebDriverWait(driver, 20).until(
webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
String source = driver.getPageSource();
driver.close();
ConverterProperties properties = new ConverterProperties().setBaseUri(url);
HtmlConverter.convertToPdf(source, new PdfWriter("result.pdf"), properties);
該選項可能會更慢一些,並且具有更多的先決條件(瀏覽器,驅動程序),但可以保證防彈JS支持。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.