好东西要分享,之前一直在使用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小时内与您取得联系。