Asp.net MVC 后台获取View()层Html并转为PDF返回

背景

之前打印时将Html链接直接返回给打印插件,由打印插件进行Html解析和转换成PDF。由于接口变动,现在需要业务系统直接返回PDF内容。考虑到MVC模式的C–>V,需要传递参数后才能形成完整的Html,遂想到后台直接获取View()内容,并将其转换为Byte[],返回 FileContentResult(pdfByte, “application/pdf”),可直接在浏览器访问链接查看PDF。

代码展示

下边是后台的调用入口

[AccessPrivilege(Type = AccessPrivilegeType.Anonymous)]
 public FileContentResult QrCodePrint(string refid)
 {
     try
     {
         var report = RequestedProcedureService.GetById(refid);  
         //需要给ViewData.Model传入页面需要的数据模型            
         ViewData.Model = report;
         var htmlText = ViewPdf("QrCodePrint", "_Layout");
         byte[] pdfByte = SelectPdfConvert(htmlText);
         return new FileContentResult(pdfByte, "application/pdf");
     }
     catch (Exception e)
     {
         Logger.Error(e.Message + "xxxxx失败");
         return null;
     }
 }

#region HtmlToPdf
//通过后台拿到View层的Html页面并转成String
private string RenderViewToString(Controller controller, string viewName, string masterName)
{
    IView view = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, masterName).View;
    using (StringWriter writer = new StringWriter())
    {
        ViewContext viewContext = new ViewContext(controller.ControllerContext, view, controller.ViewData,
            controller.TempData, writer);
        viewContext.View.Render(viewContext, writer);
        return writer.ToString();
    }
}
/// <summary>
/// 
/// </summary>
/// <param name="viewName">当前页面的名字(和Controller名字相同)</param>
/// <param name="masterName">父级页面名称(默认是"_Layout")</param>
/// <returns></returns>
private string ViewPdf(string viewName, string masterName)
{
    // Render the view html to a string.
    string htmlText = RenderViewToString(this, viewName, masterName);
    return htmlText;
}

//Select.HtmlToPdf
private byte[] SelectPdfConvert(string html)
{
    byte[] res = null;
    using (MemoryStream ms = new MemoryStream()) { 
        SelectPdf.HtmlToPdf converter = new SelectPdf.HtmlToPdf();
        PdfDocument doc = new PdfDocument();
        var docStr = converter.ConvertHtmlString(html);
        doc.Append(docStr);
        //doc.Save可以传入文件路径如:xx.pdf。在此需要返回byte,所以写入到MemoryStream中
        doc.Save(ms);
        res = ms.ToArray();
        doc.Close();
    }
    return res;
}
#endregion

Html页面内容(Model为后台传入的参数):

<!DOCTYPE html>
@{
    Layout = null;
    var locationName = Model.LocationName;
    var patientName = Model.PatientName;
    var patientId = Model.PatientId;
    var modalityType = Model.ModalityType_Name;
    var startTime = Model.StartTime;
    var qrCode = Model.QrCode;
}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div style="float: left;">
    <div id="location">@locationName</div>
    <div id="patientId">@patientId</div>
    <div id="patientName">@patientName</div>
    <div id="modalityType">@modalityType</div>
    <div id="startTime">@startTime</div>
    <div style="font-size: xx-small;">请用手机扫描二维码</div>
    <div style="font-size: xx-small;">查看本次检查的影像和报告</div>
</div>
<img src="data:image/png;base64,@qrCode" style="height: 100px; width: 100px;"/>
</body>
</html>

访问效果如下:
简单页面展示
过程总结:

  1. 获取View层的Html过程中,出错的地方有:ViewName,masterName和ViewData的传入(ViewData需要在后台传入,见代码)在这里插入图片描述
    参考的资料:
    https://www.cnblogs.com/LD13/articles/LD13_1001.html

  2. Html内容Text转PDF过程遇到的问题:
    (1)使用HtmlRender和HtmlRender.PdfSharp碰到的问题:中文字体无法显示。找了很多资料,无果。
    (2)使用ITextSharp碰到的问题:对Html内容语法检查较为严格,对于复杂的页面不友好。
    (3)使用Select.HtmlToPdf,解决问题,且调用简单。
    参考资料地址: https://blog.csdn.net/qq_40677590/article/details/102874012

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值