首先这是一个公司的老项目,使用的是 .Net Framework 4 与 MVC 4。之前使用的是 ephtmltopdf 将HTML代码转换为PDF。在 Windows Server 2008 上没有说明问题。但是部署在 Windows Server 2012上发现,生成的PDF会有重复,空白页的情况,为了解决这个问题。打算使用puppeteer-sharp来生成PDF,避免依赖IE的问题。
目前 puppeteer-sharp 只支持 .NET Framework 4.6.1 and .NET Core 2.0,为了使用这个库,先把原有的项目的目标 Framework 升级到 .NET Framework 4.6.1。这里只修改了项目的目标框架为 .NET Framework 4.6.1 不升级 MVC。在修改的时候要先确认目前引用的项目是否与 .NET Framework 4.6.1 兼容。还在老项目只有 Newtonsoft.Json 这个库不兼容,把 Newtonsoft.Json 升级一下,并且修改项目的 packages.config 文件。
把 targetFramework="net40"
改为 targetFramework="net461"
然后清理解决方案,重新获取Nuget包即可。
把 web.config 中的 <httpRuntime targetFramework="4.0" />
修改为 <httpRuntime targetFramework="4.6.1" />
, <compilation debug="true" targetFramework="4.0" />
修改为 <compilation debug="true" targetFramework="4.6.1" />
要使用 puppeteer-sharp 生成PDF,目前是先把razor模板生成为string,然后传给 puppeteer-sharp 生成为PDF。
View to string的方法:
public static string RenderViewToString(this Controller controller, string viewPath, object model = null, bool partial = false)
{
var context = controller.ControllerContext;
// first find the ViewEngine for this view
ViewEngineResult viewEngineResult = partial ? ViewEngines.Engines.FindPartialView(context, viewPath) : ViewEngines.Engines.FindView(context, viewPath, null);
if (viewEngineResult == null)
throw new FileNotFoundException("View cannot be found.");
// get the view and attach the model to view data
var view = viewEngineResult.View;
context.Controller.ViewData.Model = model;
string result = null;
using (var sw = new StringWriter())
{
var ctx = new ViewContext(context, view, context.Controller.ViewData, context.Controller.TempData, sw);
view.Render(ctx, sw);
result = sw.ToString();
}
return result;
}
首先引入 PuppeteerSharp 与 PuppeteerSharp.AspNetFramework 这两个包
到淘宝镜像选择对应的chrome版本(我选择的是Win_x64/809590/chrome-win.zip)解压到本地
在调用 PuppeteerSharp 的时候需要指定 ExecutablePath 或者由 PuppeteerSharp 自行下载,指定的话就去上述地址下载好并解压到本地
string to pdf 方法
private static readonly string HeaderTemplate =
"<div id=\"header-template\" style=\"margin: 0 auto;font-size:10px !important; color:#808080;\"></div>";
private static readonly string FooterTemplate =
"<div id=\"footer-template\" style=\"margin: 0 auto;font-size:10px !important; color:#808080;\">- FooterTemplate - </div>";
public static async Task ExpertPdfAsync(string html, string savePath)
{
var executablePath = ConfigurationManager.AppSettings["chrome"];
if (string.IsNullOrWhiteSpace(executablePath) || !File.Exists(executablePath))
{
throw new Exception("请检查web.config的chrome设置");
}
// 可以去淘宝的镜像下载
using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions()
{
Headless = true,
TransportFactory = AspNetWebSocketTransport.AspNetTransportFactory,
ExecutablePath = "D:\\chromeDownload\\chrome-win\\chrome.exe"
}).ConfigureAwait(false))
using (var page = await browser.NewPageAsync())
{
await page.SetContentAsync(html);
await page.PdfAsync(savePath, new PdfOptions()
{
// Format = PaperFormat.A4,
PrintBackground = true,
PreferCSSPageSize = true,
MarginOptions = new MarginOptions
{
Left = "0.4in",
Right = "0.4in",
Top = "0.4in",
Bottom = "0.4in"
},
DisplayHeaderFooter = true,
HeaderTemplate = HeaderTemplate,
FooterTemplate = FooterTemplate,
});
}
}
在本地测试的时候,生成PDF一切正常,但是在服务器端生成PDF的时候报了一个没有找到 System.ValueTuple.dll
的错误。
搜索 PuppeteerSharp 项目的 issues 得到解决方法如下
在 web.config 的节点添加
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<!--增加以下内容-->
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
在引用 PuppeteerSharp 的项目中卸载项目,在.csproj文件中的PropertyGroup节点添加
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
重新build解决方法即可!
在.Net Asp Mvc 4中使用 HTML to PDF功能
原文:https://www.cnblogs.com/lihaocc/p/13960130.html