好東西要分享,之前一直在使用wkhtmltopdf進行pdf文件的生成,常用的方式就是先安裝wkhtmltopdf,然后在程序中用命令的方式將對應的html生成pdf文件,簡單而且方便;但重復的編碼使得想在wkhtmltopdf基礎上進行封裝,偶然間發現有小伙伴已經封裝的還不錯啦,常用的功能都已經實現,源碼地址:https://github.com/fpanaccia/Wkhtmltopdf.NetCore。
作者將其打包成Nuget包(Wkhtmltopdf.NetCore),直接引入使用即可;
既然用到了.NetCore,肯定就要考慮到跨平臺兼容性,對于wkhtmltopdf之前一直是在Windows上使用,還沒有在其他平臺嘗試;這個包封裝的行不行,拉出來遛遛就知道啦,接下來就試試:
1. 建個API項目,引入包和兼容對應平臺的wkhtmltopdf執行文件;
注: 默認依賴的wkhtmltopdf執行文件需要存放在Rotativa目錄下,可以自定義名稱,如果自定義,需要再注冊服務時指定對應的文件名;這里的wkhtmltopdf已經根據不同平臺進行編譯打包了,無需安裝,這些文件在源碼那就有;
2.創建PDFTestController控制器,添加如下接口進行測試;
首先把生成pdf的服務注入進來,后續直接使用就可以啦:
接下來就開始寫接口啦,這里只是測試,代碼冗余沒有考慮,在實際項目中小伙伴可以根據自己需求進行封裝;
ConvertOptions默認封裝了以下屬性,小伙伴也可以自定義擴展,只要繼承IConvertOptions即可,這里就不演示的,因為官方有對應的案例,下伙伴下去搞搞,wkhtmltopdf的參數挺多的,都可以進行封裝使用。
根據指定視圖生成對應的pdf效果,如下:
根據指定視圖生成對應的pdf效果,如下:
如上基本的使用演示就說那么多,使用還是很簡單,小伙伴后續可以根據自己的需要進行相關擴展;當然還有其他功能,比如設置頁眉/頁腳等,作者提供有對應的案例;這里不說那么多,不然又是長文。
3. 小伙伴用的時候可能會遇到的問題
看見這個錯我懵的,一頓搜索猛如虎,還是沒找到答案;冷靜下來,重新捋捋,原來是自己在犯傻;
兩個問題需要解決,1.上傳到Linux下的wkhtmltopdf沒有給執行權限;2.可能環境缺少對應的依賴庫;
設置可執行權限
在Linux環境下,可以通過ll命令查看權限,剛開始是沒有權限的,只需要執行chmod 777 wkhtmltopdf命令,執行權限就有了,如下圖中紅框中的x就是可執行權限;關于Linux常用命令后續單獨整理一篇分享吧,這里先不延伸。
安裝缺少的依賴庫
可執行權限開啟之后,別急著去訪問頁面,這樣可能還是錯誤。因為可能缺少依賴庫,那咋知道缺少呢,我是直接執行wkhtmltopdf,執行成功就沒啥,不成功就會報缺少相關依賴,然后直接安裝就行啦;執行./wkhtmltopdf https://www.baidu.com ./test.pdf試試就知道啦,因為wkhtmltopdf本身是可以單獨運行的,并不依賴我們寫的程序。
鏈接: https://pan.baidu.com/s/1jikC0DUkpEzpXL5ysjEQPA 提取碼: tn4j ;
將下載下來的字體解壓,然后拷貝到Linux下的 /usr/share/fonts目錄下即可
最后這樣應該就沒啥問題啦,剩下的就交給小伙伴自己摸索搞實踐吧;
此文源碼地址:https://github.com/zyq025/DotNetCoreStudyDemo
wkhtmltopdf官網地址:https://wkhtmltopdf.org/
使用還是很簡單的,常規的需求沒啥問題,如果需要功能定制化,小伙伴可以參考源碼,自己封裝一個(封裝思路不難的); 如果小伙伴有比較好的導出庫,免費開源的那種,一起分享出來玩玩。
感謝小伙伴的:點贊、收藏和評論,下期繼續~~~
一個被程序搞丑的帥小伙,關注"Code綜藝圈",跟我一起學~~~
于IE瀏覽器和W3C瀏覽器的差異性,事件處理的方式有很大不一樣,具體現在:
所以如何提供一個一致的事件處理接口很重要,下面是其中一種解決方案。代碼如下:
var addEvent,removeEvent;
(function(){
/*
*跨瀏覽器的事件追加函數
*集中管理事件,有效防止內存泄漏
*/
function addEvent(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else {
// 附加事件處理函數一個唯一標識符
if (!handler.$$guid) handler.$$guid=addEvent.guid++;
// 為元素每個事件創建一個散列表
if (!element.events) element.events={};
// 為元素建立某個事件類型對應處理函
//數的散列表
var handlers=element.events[type];
if (!handlers) {
handlers=element.events[type]={};
// 把默認的事件處理函數作為第一個事
//件處理函數作為第一個事件處理函數
if (element["on" + type]) {
handlers[0]=element["on" + type];
}
}
// 保存當前的事件處理函數
handlers[handler.$$guid]=handler;
// 設置全局事件處理函數為默認事件處
//理函數
element["on" + type]=handleEvent;
}
};
// 唯一標識符發生器
addEvent.guid=1;
/*
*移除事件處理函數
*/
function removeEvent(element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else {
// 從散列表刪除事件處理函數
if (element.events && element.events[type]) {
delete element.events[type][handler.$$guid];
}
}
};
/*
*全局事件處理函數,所有的事件處理函數
*均委托其進行處理,this指向當前元素
*/
function handleEvent(event) {
var returnValue=true;
// 包裝事件對象,考慮了框架窗體(IE特殊
//處理)
event=event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
// 獲取事件處理函數散列表的引用
var handlers=this.events[event.type];
// 執行每一個事件處理函數
for (var i in handlers) {
this.$$handleEvent=handlers[i];
if (this.$$handleEvent(event)===false) {
returnValue=false;
}
}
return returnValue;
};
/*
*修復IE瀏覽器的不兼容性
*/
function fixEvent(event) {
// 轉換成W3C事件標準
event.preventDefault=fixEvent.preventDefault;
event.stopPropagation=fixEvent.stopPropagation;
return event;
};
fixEvent.preventDefault=function() {
this.returnValue=false;
};
fixEvent.stopPropagation=function() {
this.cancelBubble=true;
};
})();
優點如下:
文作為一個純CSS3實現網格的示例,在不使用table標簽,僅僅利用div標簽及flex布局,用flexbox及相關屬性來實現一個帶有表頭和頁眉的跨行、跨列的表格。
廢話不多講,直接上代碼:
CSS代碼如下:
HTML代碼如下:
效果圖如下:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。