序言
環境要求:在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);
}