整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          java將html轉為pdf


          html轉為pdf的組件有很多,但是還沒有哪一款能達到這個效果,其只要原因是wkhtmltopdf使用webkit網頁渲染引擎開發的用來將 html轉成 pdf的工具,可以跟多種腳本語言進行集成來轉換文檔。但是就使用簡便性來說還是itext等組件占據優勢,如果你要轉換格式有比較高的要求,那么wkhtmltopdf絕對是不二之選!

          下載路徑

          官網地址 wkhtmltopdf.org/

          github地址 github.com/wkhtmltopdf…

          使用方法

          1. windows直接使用:只要在windows命令行中輸入c:\wkhtmltopdf.exe my.oschina.net/papio/blog/… c:\blog.pdf 就可以把這篇文章轉成pdf,并保存到C盤根目錄。
          2. java調用:java中調用wkhtmltopdf的命令Runtime.getRuntime().exec("c:\wkhtmltopdf.exe my.oschina.net/papio/blog/… c:\blog.pdf")就可以實現轉換。

          java調用demo

          public class HtmlToPdfInterceptor extends Thread { private InputStream is; public HtmlToPdfInterceptor(InputStream is){ this.is = is; } public void run(){ try{ InputStreamReader isr = new InputStreamReader(is, "utf-8"); BufferedReader br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { System.out.println(line.toString()); //輸出內容 } }catch (IOException e){ e.printStackTrace(); } }}public class HtmlToPdf { //wkhtmltopdf在系統中的路徑 private static final String toPdfTool = "D:\wkhtmltopdf\bin\wkhtmltopdf.exe"; /** * html轉pdf * @param srcPath html路徑,可以是硬盤上的路徑,也可以是網絡路徑 * @param destPath pdf保存路徑 * @return 轉換成功返回true */ public static boolean convert(String srcPath, String destPath){ File file = new File(destPath); File parent = file.getParentFile(); //如果pdf保存路徑不存在,則創建路徑 if(!parent.exists()){ parent.mkdirs(); } StringBuilder cmd = new StringBuilder(); cmd.append(toPdfTool); cmd.append(" "); cmd.append(" --header-line");//頁眉下面的線 cmd.append(" --header-center 這里是頁眉這里是頁眉這里是頁眉這里是頁眉 ");//頁眉中間內容 //cmd.append(" --margin-top 30mm ");//設置頁面上邊距 (default 10mm) cmd.append(" --header-spacing 10 ");//(設置頁眉和內容的距離,默認0) cmd.append(srcPath); cmd.append(" "); cmd.append(destPath); boolean result = true; try{ Process proc = Runtime.getRuntime().exec(cmd.toString()); HtmlToPdfInterceptor error = new HtmlToPdfInterceptor(proc.getErrorStream()); HtmlToPdfInterceptor output = new HtmlToPdfInterceptor(proc.getInputStream()); error.start(); output.start(); proc.waitFor(); }catch(Exception e){ result = false; e.printStackTrace(); } return result; } public static void main(String[] args) { HtmlToPdf.convert("https://my.oschina.net/papio/blog/835645", "d:/wkhtmltopdf.pdf"); }}復制代碼

          wkhtmltopdf 參數詳解

          wkhtmltopdf [OPTIONS]... <input file> [More input files] <output file>常規選項 --allow <path> 允許加載從指定的文件夾中的文件或文件(可重復) --book* 設置一會打印一本書的時候,通常設置的選項 --collate 打印多份副本時整理 --cookie <name> <value> 設置一個額外的cookie(可重復) --cookie-jar <path> 讀取和寫入的Cookie,并在提供的cookie jar文件 --copies <number> 復印打印成pdf文件數(默認為1) --cover* <url> 使用HTML文件作為封面。它會帶頁眉和頁腳的TOC之前插入 --custom-header <name> <value> 設置一個附加的HTTP頭(可重復) --debug-javascript 顯示的javascript調試輸出 --default-header* 添加一個缺省的頭部,與頁面的左邊的名稱,頁面數到右邊,例如: --header-left '[webpage]' --header-right '[page]/[toPage]' --header-line --disable-external-links* 禁止生成鏈接到遠程網頁 --disable-internal-links* 禁止使用本地鏈接 --disable-javascript 禁止讓網頁執行JavaScript --disable-pdf-compression* 禁止在PDF對象使用無損壓縮 --disable-smart-shrinking* 禁止使用WebKit的智能戰略收縮,使像素/ DPI比沒有不變 --disallow-local-file-access 禁止允許轉換的本地文件讀取其他本地文件,除非explecitily允許用 --allow --dpi <dpi> 顯式更改DPI(這對基于X11的系統沒有任何影響) --enable-plugins 啟用已安裝的插件(如Flash --encoding <encoding> 設置默認的文字編碼 --extended-help 顯示更廣泛的幫助,詳細介紹了不常見的命令開關 --forms* 打開HTML表單字段轉換為PDF表單域 --grayscale PDF格式將在灰階產生 --help Display help --htmldoc 輸出程序HTML幫助 --ignore-load-errors 忽略claimes加載過程中已經遇到了一個錯誤頁面 --lowquality 產生低品質的PDF/ PS。有用縮小結果文檔的空間 --manpage 輸出程序手冊頁 --margin-bottom <unitreal> 設置頁面下邊距 (default 10mm) --margin-left <unitreal> 將左邊頁邊距 (default 10mm) --margin-right <unitreal> 設置頁面右邊距 (default 10mm) --margin-top <unitreal> 設置頁面上邊距 (default 10mm) --minimum-font-size <int> 最小字體大小 (default 5) --no-background 不打印背景 --orientation <orientation> 設置方向為橫向或縱向 --page-height <unitreal> 頁面高度 (default unit millimeter) --page-offset* <offset> 設置起始頁碼 (default 1) --page-size <size> 設置紙張大小: A4, Letter, etc. --page-width <unitreal> 頁面寬度 (default unit millimeter) --password <password> HTTP驗證密碼 --post <name> <value> Add an additional post field (repeatable) --post-file <name> <path> Post an aditional file (repeatable) --print-media-type* 使用的打印介質類型,而不是屏幕 --proxy <proxy> 使用代理 --quiet Be less verbose --read-args-from-stdin 讀取標準輸入的命令行參數 --readme 輸出程序自述 --redirect-delay <msec> 等待幾毫秒為JS-重定向(default 200) --replace* <name> <value> 替換名稱,值的頁眉和頁腳(可重復) --stop-slow-scripts 停止運行緩慢的JavaScripts --title <text> 生成的PDF文件的標題(第一個文檔的標題使用,如果沒有指定) --toc* 插入的內容的表中的文件的開頭 --use-xserver* 使用X服務器(一些插件和其他的東西沒有X11可能無法正常工作) --user-style-sheet <url> 指定用戶的樣式表,加載在每一頁中 --username <username> HTTP認證的用戶名 --version 輸出版本信息退出 --zoom <float> 使用這個縮放因子 (default 1) 頁眉和頁腳選項--header-center* <text> (設置在中心位置的頁眉內容) --header-font-name* <name> (default Arial) (設置頁眉的字體名稱)--header-font-size* <size> (設置頁眉的字體大小)--header-html* <url> (添加一個HTML頁眉,后面是網址)--header-left* <text> (左對齊的頁眉文本)--header-line* (顯示一條線在頁眉下)--header-right* <text> (右對齊頁眉文本)--header-spacing* <real> (設置頁眉和內容的距離,默認0)--footer-center* <text> (設置在中心位置的頁腳內容) --footer-font-name* <name> (設置頁腳的字體名稱) --footer-font-size* <size> (設置頁腳的字體大小default 11)--footer-html* <url> (添加一個HTML頁腳,后面是網址)--footer-left* <text> (左對齊的頁腳文本)--footer-line* 顯示一條線在頁腳內容上)--footer-right* <text> (右對齊頁腳文本)--footer-spacing* <real> (設置頁腳和內容的距離)./wkhtmltopdf --footer-right '[page]/[topage]' http://www.baidu.com baidu.pdf./wkhtmltopdf --header-center '報表' --header-line --margin-top 2cm --header-line http://192.168.212.139/oma/ oma.pdf表內容選項中 --toc-depth* <level> Set the depth of the toc (default 3) --toc-disable-back-links* Do not link from section header to toc --toc-disable-links* Do not link from toc to sections --toc-font-name* <name> Set the font used for the toc (default Arial) --toc-header-font-name* <name> The font of the toc header (if unset use --toc-font-name) --toc-header-font-size* <size> The font size of the toc header (default 15) --toc-header-text* <text> The header text of the toc (default Table Of Contents) --toc-l1-font-size* <size> Set the font size on level 1 of the toc (default 12) --toc-l1-indentation* <num> Set indentation on level 1 of the toc (default 0) --toc-l2-font-size* <size> Set the font size on level 2 of the toc (default 10) --toc-l2-indentation* <num> Set indentation on level 2 of the toc (default 20) --toc-l3-font-size* <size> Set the font size on level 3 of the toc (default 8) --toc-l3-indentation* <num> Set indentation on level 3 of the toc (default 40) --toc-l4-font-size* <size> Set the font size on level 4 of the toc (default 6) --toc-l4-indentation* <num> Set indentation on level 4 of the toc (default 60) --toc-l5-font-size* <size> Set the font size on level 5 of the toc (default 4) --toc-l5-indentation* <num> Set indentation on level 5 of the toc (default 80) --toc-l6-font-size* <size> Set the font size on level 6 of the toc (default 2) --toc-l6-indentation* <num> Set indentation on level 6 of the toc (default 100) --toc-l7-font-size* <size> Set the font size on level 7 of the toc (default 0) --toc-l7-indentation* <num> Set indentation on level 7 of the toc (default 120) --toc-no-dots* Do not use dots, in the toc輪廓選項 --dump-outline <file> 轉儲目錄到一個文件 --outline 顯示目錄(文章中h1,h2來定) --outline-depth <level> 設置目錄的深度(默認為4)頁腳和頁眉 * [page] 由當前正在打印的頁的數目代替 * [frompage] 由要打印的第一頁的數量取代 * [topage] 由最后一頁要打印的數量取代 * [webpage] 通過正在打印的頁面的URL替換 * [section] 由當前節的名稱替換 * [subsection] 由當前小節的名稱替換 * [date] 由當前日期系統的本地格式取代 * [time] 由當前時間,系統的本地格式取代
          作者:曹元
          鏈接:https://juejin.im/post/6856547881873047559
          來源:掘金
          著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

          持原創,共同進步!請關注我,后續分享更精彩!

          概述

          項目中經常有生成圖表報告的需求。實現的方式有很多,下面幾種方案,各有優缺點。

          純java后端實現:后端JFreeChart等繪制庫畫好圖表,再通過itext庫導出為pdf。該方案能實現簡單的圖表功能,樣式、格式調整等可能會花大量時間。適合中小型報表開發項目。

          前端繪制圖表,后端運行時命令調用wkhtmltopdf生成pdf:后端通過運行時命令調用node js,js使用wkhtmltopdf庫動態訪問報表url地址,HTML內容渲染完成后生成pdf文件。該方案,使用純前端js繪制圖表,能實現復雜需求。但wkhtmltopdf庫對不同瀏覽器的js存在兼容性問題,導出成pdf文件時存在各種坑,在單頁面技術支持還不太成熟。適合豐富報表的pdf導出,但兼容性問題維護成本太高。

          前端繪制圖表,后端運行時命令調用puppeteer生成pdf:后端通過運行時命令調用node js,js使用puppeteer庫動態訪問報表url地址,HTML內容渲染完成后生成pdf文件。該方案和wkhtmltopdf方案類似,但兼容性更好。puppeteer是 Chrome 開發團隊在 2017 年發布的一個 Node.js 包,用來模擬 Chrome 瀏覽器的運行。可以在無界面的環境中運行Chrome或通過命令行、程序語言操作 Chrome。理論上Chrome中顯示的圖表,就能通過該庫生成一致的pdf文件內容,不用浪費很多時間在頁面樣式和兼容性問題上。

          本文選擇puppeteer方案介紹如何生成一個pdf報表。細心的小伙伴可能注意到了,既然puppeteer是js庫,為什么不直接前端導出pdf,干嘛這么麻煩還通過后端繞一圈來實現?

          這主要出于需求和用戶體驗的考慮,有些業務場景需要通過api接口動態生成pdf報表,不需要用戶訪問界面。如果生成的pdf的報表很大,直接在用戶端生成,可能占用大量客戶端資源,導致頁面崩潰或假死,從而影響使用體驗。

          實現

          1.先安裝NodeJs,網上教程很多,本文不再贅述。

          2.安裝puppeteer依賴,如果npm下載不成功就使用cnpm命令(cnpm需要先安裝)

          npm install puppeteer --save

          3.在安裝puppeteer依賴的目錄下創建page2pdf.js

          const puppeteer = require('puppeteer');
          const options = process.argv;
          var siteUrl;
          //執行 node page2pdf.js https://www.baidu.com
          
          (async() => {
          if(options.length>=3){
              siteUrl=options[2];
              //types=options[3];
          	//console.log(siteUrl);
          }
          
          const browser = await puppeteer.launch();
          const page = await browser.newPage();
          
          //console.log(options.length);
          //console.log(options[0]);
          //console.log(options[1]);
          //console.log(options[2]);
          //console.log(options[3]);
          
          const userAgent = "Mozilla/5.0 (Linux; Android 8.1.0; MI 8 Build/OPM1.171019.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/62.0.3202.84 Mobile Safari/537.36";
          page.setUserAgent(userAgent);
          
          await page.setViewport({ width: 1000, height: 1080 });
          
          //await page.setViewport({ width: 480, height: 800,isMobile: true}); 
          
          //通過css樣式可見,動態設置站點加載完成標識。
          //page.waitForSelector('img').then(() => console.log('siteUrl with page load success: ' + siteUrl));
          
          await page.goto(siteUrl, {timeout: 10*60000, waitUntil: 'networkidle2'});
          
          /**await page.goto(siteUrl, {timeout: 10*60000, waitUntil: 'networkidle2'})
          			.catch(e => {
          			  console.log(siteUrl+" is error:"+e);
          			  browser.close()
          			});*/
          
          const pdf = await page.pdf({
          		path: 'page.pdf', //便于測試驗證,實際使用時可屏蔽
          		format: 'A4'
          	});
          	
          await browser.close();
          process.stdout.write(pdf);
          })();

          page2pdf.js文件引入puppeteer依賴庫,通過傳入siteUrl參數訪問HTML page頁面,page.pdf生成文件,再通過process.stdout.write(pdf)返回java后臺。

          4.創建java PuppeteerHtmlToPdf.java文件

          /**
           * 用谷歌提供的node實現的Puppeteer,實現網頁生成pdf文件
           */
          public class PuppeteerHtmlToPdf {
              /**
               * html轉pdf,直接通過流輸出到瀏覽器
               * @param response 瀏覽器響應
               * @param fileName 文件名稱
               * @param puppeteerjs 要采用哪個js文件執行
               * @param webSiteUrl 要生成pdf的網頁
               */
              public static void parseHtml2Pdf(HttpServletResponse response, String fileName, String puppeteerjs, String webSiteUrl) {
                  try {
                      Runtime rt = Runtime.getRuntime();
                      Process p = rt.exec("node "+puppeteerjs+" "+webSiteUrl);
                      InputStream is = p.getInputStream();
                      BufferedInputStream bf=new BufferedInputStream(is);
                      byte[] data = IOUtils.toByteArray(bf);
                      fileName = URLEncoder.encode(fileName, "UTF-8");
                      response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
                      response.addHeader("Content-Length", "" + data.length);
                      response.setContentType("application/octet-stream;charset=UTF-8");
                      OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
                      outputStream.write(data);
                      outputStream.flush();
                      outputStream.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
          
              }
          }

          5.報表生成

          page2pdf.js頁面目錄打開命令行,執行指令。


          運行指令,生成pdf

          node page2pdf.js https://www.baidu.com


          查看對應目錄,已動態生成了一個page.pdf文件


          打開pdf文件,對應HTML內容已生成。

          小結

          本文介紹了報表導出pdf的3種方式,通過優缺點分析,詳細闡述了puppeteer的實現方式。并通過百度頁面的pdf導出做了演示。

          希望本文對有類似報表pdf導出需求的小伙伴有所參考和幫助。若存在不足或更好方案,請留言討論。

          在前面:java作為一門世界級編程語言金字塔頂尖的語言。需要大量的練習、練習、練習來鞏固自己所獲得的知識。冰凍三尺非一日之寒,希望大家在學習java的日子里一定一定要堅持不懈,嚴格要求。多練,多問,多百度。祝大家早日成為一名優秀的軟件工程師!

          文章摘要:此篇文章會帶領大家創建一個html最簡單的頁面,以及在頁面中增加一些簡單的內容。

          我先給大家放2張我以前教學的時候,開課前給學生畫的圖:

          這2張圖應該已經比較清晰明了的告訴你,學習java前端需要具備的一些主觀和客觀方面的東西,我就不多做解釋了,以后我的文章中,會以代碼圖片及展現效果居多,盡量減少文字的占比。讓大家對所學的知識有一個更直觀的感受。

          言歸正傳,想要編寫html代碼,首先需要一個后綴為.html的文件,這個文件怎么創建呢?最簡單的方式,建一個txt,然后把后綴改為.html,用編輯器打開,就可以編寫代碼了。

          當然,txt界面太丑,筆者這里選用sublime,該編輯器也可以直接加載一個html模板,選擇菜單→新建文件(模板)→html,當然,前提要先設置好這個模板,具體設置方法這里就不做詳細介紹了,百度上一大堆。新建完成后,產生一個代碼如下的頁面:

          然后在<body></body>標簽體之間打入一行代碼

          用瀏覽器打開該文件,顯示如下圖,說明這個html文件已經創建成功了,能夠正常的編寫代碼。

          零基礎的同學一定對剛才的代碼比較疑惑,雖然照著寫能實現功能,但是這些代碼各自又都是什么意義呢? 我用注釋的方式上圖來告訴大家:

          首先,html 的標簽分為自閉和標簽和閉合標簽

          自閉和標簽:就是沒有結束標簽,比如上圖的<meta>標簽,該標簽是沒有結束標簽相呼應的。

          閉合標簽:有開始和結束標簽,比如上圖的<html><body><h1>標簽,他們都有一個</html></body></h1>相呼應

          在上圖中,我用過了比較多的 < !-- -- >標簽,這是html里的注釋標簽,在編寫代碼的過程中,勤加注釋是一個非常非常好的習慣,不僅方便了他人也方便了以后自己代碼的維護。所以說,不加注釋的代碼都是在耍流氓。

          我們80%的頁面標簽代碼都會寫在<body></body>標簽里面,什么是標簽,至少包含< > 和標簽元素,比如<div><a><p><input>等,標簽還有標簽屬性和屬性值,標簽屬性和屬性值在第一個標簽內容中,如果是多個標簽則以空格符號分割 ,如圖:

          Div 是整個html中最常用的一個標簽元素,<div></div>類似于一個盒子,里面可以承載各種各樣的元素標簽,大家看到的所有的網站都是靠著div一個個的盒子規劃開來,最后拼接在一起的,形成了一個完整的頁面。

          那么如何去建立一個div呢?首先,我們在html的<body></body>標簽中加入一個<div></div>標簽 ,但是單純的加入標簽并不會在頁面中產生肉眼可見的東西,因為我們還要定義這個div的寬,高,背景色,邊框等等,詳見如下代碼:

          這樣的一行代碼,最后展現出來的效果是:

          我們來一點點的剖析這一行代碼:

          Style:style 是元素標簽里的一個標簽屬性,他的作用是可以定義該標簽的樣式。里面的樣式格式是xxx:xxx; 每一組樣式都是這樣的定義,冒號用來隔開樣式屬性和樣式屬性值,最后以分號結尾.

          width:定義該元素的寬

          height:定義該元素的高

          background:定義該元素的背景顏色(也可使用red,yellow等顏色定義)

          border:定義該元素的邊框

          4px 代表邊框粗細,

          solid 代表邊框樣式, 邊框樣式又分為solid(實框)、dotted(虛框)

          red代表邊框顏色,邊框顏色也可用#ccc,#112233這種形式表現

          Div里可以放入文字、圖片、標簽元素等各式各樣的東西。下面我演示一下如何放入照片:

          首先,放入照片要使用到<img>標簽,這是一個自閉和標簽,所有沒有結束標簽。

          Src代表圖片的路徑,width,height 代表圖片的寬度和高度 ,alt是圖片的描述

          這個路徑可以是相對路徑,也可以是絕對路徑。

          相對路徑:就是相對于這個網頁的路徑,比如圖片和網頁在同一個文件夾下,那么src處就直接填圖片的文件名字就可以,若建了一個文件夾images,圖片放在該文件夾中,同時這個文件夾和網頁在同一個位置,那么src所填的就是images/圖片名字.jpg

          絕對路徑:即從頭開始寫路徑,如src = “C:/xxx/xxx/xxx/xxx.jpg”

          假設我現在的圖片位置和網頁位置同處一處

          最后的效果:

          我這里改大了DIV的寬度和高度,若圖片所設的寬高大于DIV的寬度高度,那么將會發生溢出的情況,同學們可以自己去試一下,這種溢出的情況也有對應的標簽可以做調整,這個我們后面再講。

          這邊特別提醒一點,如果div沒有設定寬度width,則默認為等同瀏覽器寬度的寬度,若div沒有設定高度,則該div根據div中內容進行高度的伸縮,div中的內容有多高,div就有多高,如圖,我把width和height全部去掉:

          上圖width和height全部去掉,所以,width默認跟瀏覽器寬度等寬,高度為圖片的高度。

          文字的話就比較簡單了,代碼貼上:

          最后結果:

          第二句文字才是div創建出來的文字,我解釋一下style里面的樣式:

          Font-size:文字大小,px為單位(像素)

          Font-family:文字樣式,分為很多,這個可以去word文檔里找找

          Font-weight:文字加粗,bold是一種默認加粗的大小。

          End.

          來源:公眾號“java編程”

          運行人員:中國統計網小編(微信號:itongjilove)

          微博ID:中國統計網

          中國統計網,是國內最早的大數據學習網站,公眾號:中國統計網

          http://www.itongji.cn


          主站蜘蛛池模板: 亚洲一区在线视频| 国产精品日韩欧美一区二区三区 | 亚洲一区二区三区国产精品无码 | 亚洲国产精品一区二区九九 | 久久综合九九亚洲一区| 国产一区二区不卡老阿姨| 无码日韩精品一区二区三区免费 | 国产精华液一区二区区别大吗| 国产乱码精品一区二区三区| 色窝窝无码一区二区三区| 不卡无码人妻一区三区音频| 国产精品电影一区二区三区| 3D动漫精品啪啪一区二区下载 | 亚洲变态另类一区二区三区| 久久久91精品国产一区二区三区| 日本夜爽爽一区二区三区| 国产一区二区三区小说| 夜精品a一区二区三区| 国产精品视频一区二区三区四 | 日韩精品一区二区三区老鸭窝| 中文字幕AV一区中文字幕天堂| 国产福利电影一区二区三区久久久久成人精品综合 | 中文字幕av人妻少妇一区二区| 亚洲日本一区二区三区| 国产一区二区三区不卡观| 中文字幕一区二区三区日韩精品| 国产一区二区三区日韩精品| 免费看无码自慰一区二区| 无码少妇一区二区三区芒果| 亚洲精品无码一区二区| 亚洲熟女乱色一区二区三区| 国产一区在线mmai| 日本一区二区视频| 亚洲精品无码一区二区| 国产欧美色一区二区三区| 日韩美女在线观看一区| 国产成人一区二区三区精品久久| 免费无码一区二区三区蜜桃大| 国产成人无码aa精品一区| 国产一区二区三区播放| 国产激情精品一区二区三区|