MVC中网页导出为PDF怎么实现

如题所述

最近做过一个将页面表格导出至PDF的功能,现在将它整理出来,以备不时之需。
   PDF模板是用的是.net报表文件(.rdlc),原理就是将数据填充到报表文件中,利用Microsoft.Reporting.WebForms.LocalReport类的方法,输出PDF字节流,然后,通过定义Response的HTTP标头定义,在浏览器输出PDF文件。
   以下是关键部分的代码:
   1. 首先,准备一个输出PDF字节流的方法:

using System;
using System.Collections.Generic;
using ATA.Toeic.Models;
using ATA.Toeic.DAL;
using System.IO;
using Microsoft.Reporting.WebForms;
namespace ATA.Toeic.BLL

    public class AdmissionTicketBLL 
    { 
        private RegistrationDAL dal = new RegistrationDAL(); 

        /// <summary>
        /// 『单个导出』 
        /// 导出包含一张准考证的pdf文件 
        /// </summary> 
        /// <param name="addmissionFormId">准考证号</param> 
        /// <param name="reportPath">报表模板路径</param> 
        /// <returns>pdf文件字节流</returns> 
        public byte[] ExportTicket(string addmissionFormId, string reportPath, out string mimeType) 
        { 
            List<string> arrId = new List<string>(); 
            arrId.Add(addmissionFormId); 
            return ExportTicket(arrId, reportPath, out mimeType); 
        } 
        
        /// <summary> 
        /// 『批量导出』 
        /// 导出多张准考证的pdf文件 
        /// </summary> 
        /// <param name="arrAddmissionFormId">需要导出的准考证号</param> 
        /// <returns>pdf文件字节流</returns> 
        public byte[] ExportTicket(List<string> arrAddmissionFormId, string reportPath, out string mimeType) 
        { 
            LocalReport localReport = new LocalReport(); 
            localReport.ReportPath = reportPath; 
            // 报表对象的模板文件的路径 
            // 报表对象的数据源 
            ReportDataSource reportDataSource = new ReportDataSource("dsList", GetAdmissionTicketList(arrAddmissionFormId.ToArray()) 
            // 这个方法返回一个IList<Model>对象 ); 
            localReport.DataSources.Add(reportDataSource); 
            string reportType = "PDF"; 
            string encoding; 
            string fileNameExtension; 
            //The DeviceInfo settings should be changed based on the reportType 
            //http://msdn2.microsoft.com/en-us/library/ms155397.aspx 
            string deviceInfo = "<DeviceInfo><OutputFormat>PDF</OutputFormat></DeviceInfo>"; Warning[] warnings; string[] streams; byte[] renderedBytes;             //Render the report 
            renderedBytes = localReport.Render( reportType, deviceInfo, out mimeType, out encoding, out fileNameExtension, out streams, out warnings); 
            return renderedBytes; 
        } 
    }




 
    2. 在action中定义HTTP标头,输出PDF文件,在这里批量和单个已经没有区别了,区别包含在byte[]的字节流中。
   
[CheckServiceExpire] 
public ActionResult GetAdmissionForms(int serviceid, string Condition) 

    List<RegistrationEn> list = new RegistrationBLL().GetExamineeByCondi(serviceid, Condition); 
    if (list == null || list.Count == 0) 
        return Alert("目前没有准考证信息!", "~/Views/ExamService/SaveSuccess.aspx", new { action = "GetExamineeByPage", controller = "Registration", serviceid = serviceid }); 
    List<string> sl = new List<string>(); 
    foreach (RegistrationEn ren in list) 
        sl.Add(ren.fAdmissionFormId); 
    try 
    { 
        AdmissionTicketBLL bll = new AdmissionTicketBLL(); 
        string rdlcPath = Server.MapPath("~/Resources/AdmissionTicket.rdlc"); 
        string mimeType; 
        byte[] renderedBytes = bll.ExportTicket(sl, rdlcPath, out mimeType); 
        Response.AddHeader("content-disposition", "attachment; filename=AdmissionTicket.pdf"); 
        return File(renderedBytes, mimeType); 
    } catch { 
        return Alert("获取准考证信息出错!", "~/Views/ExamService/SaveSuccess.aspx", new { action = "GetExamineeByPage", controller = "Registration", serviceid = serviceid }); 
    } 
}

这样就可以正常导出PDF文件了。

 

  

    补充:

    如果想在页面中直接打开PDF(要求机器已安装adobe reader),则只需要修改HTTP标头的参数:

    将“Response.AddHeader("content-disposition", "attachment; filename=AdmissionTicket.pdf");”替换成“Response.AddHeader("content-disposition", string.Format("inline;filename={0}.pdf", admissionFormId));”

温馨提示:答案为网友推荐,仅供参考
第1个回答  2020-03-30
你说呢...