整合營銷服務商

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

          免費咨詢熱線:

          Java后端實現HTML網頁報表導出pdf方案

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

          概述

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

          純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導出需求的小伙伴有所參考和幫助。若存在不足或更好方案,請留言討論。

          片編輯:如何在Lightroom中創建HTML Web畫廊?



          隨著iPad和iPhone的日益普及,我們大多數人不再適合創建基于Flash的Web畫廊 - 它們無法在這些設備上輕松查看。如果您希望幾乎每個人都能夠看到您的畫廊,那么您需要將它們創建為HTML畫廊而不是Flash。

          要在Lightroom中創建Web畫廊,請首先將圖像放入集合中。這使您可以更輕松地處理圖像,并且可以保存圖庫,以便將來根據需要進行編輯。選擇您的收藏并切換到Web模塊。從“布局樣式”選項中,您可以選擇Lightroom HTML庫,或者更簡單地從屏幕左側的“模板瀏覽器”面板中選擇基于HTML的庫。如果您在預覽區域中查看,HTML圖庫模板的左下角都有字母HTML。選擇要使用的模板。


          從工具欄(如果不可見則按T鍵),如果您選擇了一個集合,請選擇所有膠片照片,這會將所有圖像添加到您的圖庫。您在編輯區域的屏幕上看到的是您的網絡圖庫的實時版本。您可以單擊任何圖像以查看它在Web上的外觀。


          打開“站點信息”面板,然后鍵入站點標題,集合標題和集合描述。如果您不想使用所有這些,只需刪除您不想使用的項目的占位符文本,并且將釋放它們在模板中占用的空間以用于您的圖像。對于“聯系信息”,請根據需要鍵入您的聯系人姓名,然后填寫“Web或郵件鏈接”,這將自動鏈接到Web畫廊中的聯系人姓名。


          您可以在圖庫中添加標識牌,如果需要,它將位于網站標題上方。如果需要,您可以通過完成Web或郵件鏈接框將其鏈接回您的站點。


          使用“調色板”選項可以更改網站模板中各種元素的顏色。

          在“外觀”面板中,您可以設置縮略圖圖像網格大小 - 默認為3 x 3,不能小于任何小,但可以大得多。如果要在圖像上顯示單元格編號,可以這樣做 - 當您需要為查看者提供一種簡單的方法來識別他們喜歡的圖像時,這非常有用。圖像按順序編號,如果您有多個頁面,則第二頁上的圖像將從第一頁的編號順序繼續。


          您可以通過調整“大小”滑塊來控制“圖像”頁面上的完整大小圖像的大小。您還可以將圖片邊框添加到圖像頁面中的圖像。請注意,“外觀”面板分為“通用設置”,“網格頁面”和“圖像頁面”,允許您進行影響整個圖庫的更改,僅影響網格頁面或僅影響圖像頁面。


          在“圖像信息”面板中,您可以選擇為圖像添加標簽。它們僅出現在圖像頁面上。您可以選擇圖像上方顯示的標題和圖像下方顯示的標題。例如,對于每一個,您可以從圖像元數據中獲取文本,并且沒有理由不能將標題設置為標題元數據,而將標題設置為您的設備元數據。


          在輸出設置中選擇較大尺寸JPG圖像的質量 - 0是低質量,100是高質量。如果要在圖像中包含元數據,請選擇要包含的內容 - 您的選擇是“僅限版權”還是“全部”。

          如果需要,還可以添加水印。如果您選擇添加水印,您將在圖像頁面和索引頁面上看到它,以便您可以檢查它是否是您想要的。選擇是否銳化圖像 - 此銳化僅在圖像輸出時應用,因此您不會在屏幕上看到它。如果您不確定要使用什么,請啟用銳化并將其設置為標準。


          完成后,單擊“創建已保存的Web畫廊” - 這是Lightroom 4中的新選項,它顯示在主編輯區域的右上角。鍵入Web庫的名稱,然后單擊“創建”。這樣做可確保庫已保存,一旦完成此操作,Lightroom將從現在開始跟蹤您的更改。將來您可以通過單擊Lightroom為您創建的特殊集合返回Web畫廊。



          配置好所有內容后,單擊“上載”以呈現庫圖像,創建必要的html代碼并將其全部自動上傳到服務器。


          Lightroom中的HTML畫廊并不是城里最漂亮的畫廊,但是幾乎任何設備都可以使用畫廊,這絕對是激勵他們使用它們代替Flash畫廊。

          字練習《清風明月》教學設計

          教學目標:

          1.通過圖片欣賞感受清風明月詩情畫意的意境美;

          2.學習從結構、用筆讀帖;https://www.shimengyuan.com/nianji/1046.html

          3.學會寫“風”,自學清、明、月寫法;學會用扇面創作品;

          4.感受書法傳統文化的豐富內涵。

          教學準備:課件、筆墨紙硯

          教學過程:https://www.renjiaoshe.com/jiaocai/454.html

          一、“清風明月”話詩情

          播放課件,師生吟誦古詩詞。“月”代表團圓、思念、美好……

          師:它是駐邊將士思親的悠悠笛聲;

          師:它是異鄉游子思鄉的徹夜無眠;www.renjiaoshe.com

          師:它是月圓之時對酒當歌的無限惆悵;

          師:它還是漂泊之人回鄉之途的心中明月!

          古人有太多的詩篇和文章來描述清風明月這般美好的畫面,今天這節課我們學習用毛筆寫清風明月這幾個字,用書法作品來表達這詩情畫意的美好和濃濃的情感。

          二、指導寫“風”字

          1.怎樣才能寫好毛筆字呢?

          (預設:觀察、讀帖;)

          2.出示:風

          師:那你來觀察這個字,應該怎樣寫?

          生1:……生2:……(預設,橫畫左低右高的斜勢;出示撇和鉤的標線,你發現什么?適時評價:被你看出來了,不簡單、好眼力、觀察仔細,而且會表達)

          過渡:我們已經從整體上把握了字的結構,再看用筆:也就是筆畫的起止、轉折、粗細的變化。

          師:把哪兩筆寫好這個字就成功一半了?

          (預設:撇和斜鉤,它們都有向內的弧度;評價:火眼金睛呀!)

          師:除了寫出向內的弧度之外,在起筆、收筆處,還有什么特點嗎?

          總結:剛才我們仔細觀察的過程就是“讀帖”,方法是先從整體把握結構,然后是筆畫的用筆。我們就用這種方法,自主學習“清、明、月”

          三、自主學寫“清、明、月”

          1.出示:清、明、月

          (1)觀察這三個字的特點,從結構、用筆上把握;

          (2)學生探究交流。

          2.學生反饋自學成果

          清:三點水,歐體的特殊寫法,筆斷意連;

          明:橫畫平行有序、下部錯落有致;

          月:兩短橫的變化、撇和鉤的位置。

          三個“月”的不同寫法:清中月、明中月、獨體月

          三個字里面都有哪個字?如果把三個“月”分別看成個性不同的人,你想用哪個詞來形容它?

          穩穩地拖住上部,端莊沉穩;撇要收斂,避讓左部,謙恭避讓;撇,瀟灑飄逸,落落大方,灑脫大方

          四、書寫展示(配樂)

          1.師范寫“風”

          2.學生練習寫“清風明月”

          3.展示點評2人(貼黑板上)

          ①師帶學生評

          ②自評

          4.個別難掌握的字二次練寫

          同學們已經學會了從結構、用筆去讀帖,并寫好一個字,不簡單!下面我們就學習用“清風明月”來完成一幅扇面作品。

          五、創作品

          1.(出示扇面)扇面不同于條幅和橫幅,請仔細看(作品貼黑板上講扇面作品的特點)

          (1)師:每個字都要對著適應扇面的形態來書寫,字在你的正前方,因此此幅扇面四個字傾斜角度各不相同。寫完一個字需要轉動紙張寫下一個字(師邊寫邊講)四個字寫得大小均勻,整體協調,正文左側應留出款字和印章。

          2.這里是老師寫字錄下的視頻,同學們像老師這樣完成扇面作品。生練習(同時播放視頻)

          3.師展示作品

          4.點評:這幾幅作品從整篇來看,四個字大小均勻,結尾有落款,有印章。再從個別字來看,結構合理,布白勻稱、舒展有度,用筆干凈利落……

          5.這節課我們學會了如何用扇面寫作品,真了不起!一節課的收官之作你最想送給誰呢?


          主站蜘蛛池模板: 国产在线无码视频一区二区三区| 制服丝袜一区在线| 日韩高清国产一区在线| 日韩一区二区在线视频| 日韩AV无码一区二区三区不卡毛片| 在线观看亚洲一区二区| 成人区人妻精品一区二区不卡视频| 无码国产精品一区二区免费I6| 国产天堂一区二区综合| 无码人妻一区二区三区在线水卜樱 | 一区二区三区四区精品| 在线观看视频一区二区| 亚洲av成人一区二区三区观看在线| 国产成人精品一区二区秒拍| 自慰无码一区二区三区| 国产伦精品一区二区免费 | 精品无码国产一区二区三区51安| 无码AV中文一区二区三区| 国产精品无码一区二区三区电影| 一区二区三区电影在线观看| 国产人妖视频一区二区破除| 国产精品盗摄一区二区在线| 国产成人一区二区在线不卡| 亚洲国产成人久久一区二区三区 | 国产suv精品一区二区6| 国产一区二区三区乱码在线观看| 亚洲高清一区二区三区电影| 欧美日韩综合一区二区三区| 国产麻豆精品一区二区三区| 在线观看一区二区三区视频| 日本精品一区二区在线播放| 一区二区免费在线观看| 久久久国产一区二区三区| 三上悠亚亚洲一区高清| 国产在线精品一区二区在线观看| 亚洲色欲一区二区三区在线观看| 亚洲AV无码一区二区二三区软件 | 日韩一区二区三区视频久久| 中文字幕亚洲一区| 一区二区三区午夜视频| 国产经典一区二区三区蜜芽|