使用 Rotativa 和 WebAPI 从 ApiController 生成 PDF



我想使用 ApiController 的 Rotativa 框架创建一个 pdf 文件。在我的项目中,没有任何视图。pdf (HTML( 的内容在数据库中。

有没有办法在没有视图和控制器上下文的情况下生成pdf?控制器上下文只能在控制器中访问,而不是在 APIController 中访问...

我找到了这个 https://github.com/JustMaier/Rotativa/tree/ed7678eefdffb3995f5b6a3e9afb18903c648df8但它需要视图

问题出在方法构建文件((...

从这里开始

var a = new Rotativa.ViewAsPdf(pdfResult);
a.FileName = request.ResultFileName;
byte[] f = a.BuildFile();

此处的 ControlerContext 可以为 null

 public byte[] BuildFile(ControllerContext context = null)
    {
        if (this.WkhtmlPath == string.Empty)
            this.WkhtmlPath = context == null ? HttpContext.Current.Server.MapPath("~/Rotativa") : context.HttpContext.Server.MapPath("~/Rotativa");
        var fileContent = this.CallTheDriver(context);
        if (string.IsNullOrEmpty(this.SaveOnServerPath) == false)
        {
            File.WriteAllBytes(this.SaveOnServerPath, fileContent);
        }
        return fileContent;
    }

。但这里不能

    protected override byte[] CallTheDriver(ControllerContext context)
    {
        // use action name if the view name was not provided
        string viewName = ViewName;
        if (string.IsNullOrEmpty(viewName))
            viewName = context.RouteData.GetRequiredString("action");
        ViewEngineResult viewResult = GetView(context, viewName, MasterName);
        string html = context.GetHtmlFromView(viewResult, viewName, Model);
        byte[] fileContent = WkhtmltopdfDriver.ConvertHtml(this.WkhtmlPath, this.GetConvertOptions(), html);
        return fileContent;
    }

我做错了什么?

Rotativa 似乎不适合您的方案。使用像DinkToPdf这样的替代库会更容易,它既不需要视图也不需要控制器上下文。您应该能够将数据库中的 HTML 与它一起使用。

如果您确实需要使用Rotativa,可以尝试以下方法:

  • 添加一个虚拟视图,使用视图模型将数据库中的 HTML 传递到该虚拟视图
  • 创建一个虚拟上下文,如本问题所示

试试这个:从称为MVC控制器的API控制器,它对我有用

接口控制器

public class DocumentsController : ApiController
{
        public HttpResponseMessage Pdf()
        {
            PDFController controller = new PDFController();
            RouteData route = new RouteData();
            route.Values.Add("action", "getPdf"); // ActionName
            route.Values.Add("controller", "PDF"); // Controller Name
            System.Web.Mvc.ControllerContext newContext = new 
            System.Web.Mvc.ControllerContext(new HttpContextWrapper(System.Web.HttpContext.Current), route, controller);
            controller.ControllerContext = newContext;
            var actionPDF = controller.getPdf(); 
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Content = new ByteArrayContent(actionPDF);// new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
            response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            response.Content.Headers.ContentDisposition.FileName = "SamplePDF.PDF";
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
            return response;
        }            
}

MVC 控制器

    public class PDFController : Controller
    {
            public Byte[]  getPDF()
            {
            var actionPDF = new Rotativa.ViewAsPdf("YOUR_VIEW_NAME") )
            {
                PageSize = Rotativa.Options.Size.A4,
                PageOrientation = Rotativa.Options.Orientation.Landscape,
               PageMargins = { Left = 1, Right = 1 }
            };
            byte[] applicationPDFData = actionPDF.BuildPdf(this.ControllerContext);
            return applicationPDFData;
        }
   }

最新更新