序言
环境要求:在centos7的docker上,.NETCORE 3.1
目标:将HTML转为PDF导出
相关测试:
Select.HtmlToPdf.NetCore,兼容性很好,使用也挺简单的,但是只支持windows系统;
DinkToPdf、Haukcode.WkHtmlToPdfDotNet等类库在centos要支持各种类库,最后放弃了;
还有个itextsharp没有测试,有文章表示它对css的支持比较弱。
Haukcode.WkHtmlToPdfDotNet简介
地址:https://github.com/HakanL/WkHtmlToPdf-DotNet
它使用P/invoke方式将wkhtmltopdf打包为linux的libwkhtmltox.so库来调用;
相关技术文章:https://www.cnblogs.com/kelelipeng/p/10654315.html
HTML页面编写
样式注意要点:要有实际内容,转为PDF才会展示;
陷阱1:宽度百分比无效;
陷阱2:同行DIV要使用display:inline-block;
陷阱3:div内容要垂直居中,通过高度控制,在内部添加2个div,第二个为空内容(?);
类库使用
github:https://github.com/fpanaccia/Wkhtmltopdf.NetCore
示例:https://github.com/fpanaccia/Wkhtmltopdf.NetCore.Example
引用类库
在nuget添加Wkhtmltopdf.NetCore,在Startup.cs添加引用
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddWkhtmltopdf();
}
然后,将示例的文件夹Rotativa文件夹拷贝到WEB项目,包含不同操作系统的wkhtmltopdf
dockerfile配置
将windows下的字体拷到到wwwroot/fonts下的微软雅黑和宋体拷到docker里面,并授权wkhtmltopdf;
donetcore3是自己封装的镜像,已添加libgdiplus;
FROM donetcore3:v1
WORKDIR /app
COPY . .
COPY ./wwwroot/fonts/simsun.ttc /usr/share/fonts/ty/simsun.ttf
COPY ./wwwroot/fonts/msyh.ttc /usr/share/fonts/ty/msyh.ttf
COPY ./wwwroot/fonts/msyhl.ttc /usr/share/fonts/ty/msyhl.ttf
COPY ./wwwroot/fonts/msyhbd.ttc /usr/share/fonts/ty/msyhbd.ttf
EXPOSE 80/tcp
ENV ASPNETCORE_ENVIRONMENT Production
#测试多语言 启用下面参数 指示docker默认环境的语言为utf8
ENV LC_ALL zh-Hans.UTF-8
ENV LANG zh-Hans.UTF-8
ENV LANGUAGE zh-Hans.UTF-8
RUN chmod 755 /app/Rotativa/Linux/wkhtmltopdf
ENTRYPOINT ["dotnet", "Monitor.Web.dll"]
使用
按A4横向生成PDF
[HttpGet]
[Route("GetPage")]
public IActionResult GetPage()
{
var options = new ConvertOptions
{
//HeaderHtml = "http://localhost/header.html",
HeaderSpacing = 0,
FooterSpacing = 0,
IsGrayScale = true,
PageSize = Wkhtmltopdf.NetCore.Options.Size.A4,
PageMargins = new Wkhtmltopdf.NetCore.Options.Margins() { Bottom = 0, Left = 0, Right = 0, Top = 0 },
PageOrientation = Wkhtmltopdf.NetCore.Options.Orientation.Landscape
};
_generatePdf.SetConvertOptions(options);
string htmlCode = "";
using (WebClient client = new WebClient())
{
#if DEBUG
htmlCode = client.DownloadString("http://localhost:5020/print/DyColdStoragePrint");
#else
htmlCode = client.DownloadString("http://127.0.0.1/print/DyColdStoragePrint");
#endif
}
var pdf = _generatePdf.GetPDF(htmlCode);
var path = Path.Combine("wwwroot", DateTime.UtcNow.Ticks.ToString() + ".pdf");
using (var stream = new FileStream(path, FileMode.Create))
{
stream.Write(pdf, 0, pdf.Length);
}
return Content(path);
}