使用Rotativa和WebAPI从ApiController生成PDF

时间:2018-04-11 12:36:00

标签: c# asp.net-web-api2 rotativa

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

是否可以在没有View和ControllerContext的情况下生成pdf?控制器上下文只能在Controller中访问,而不能在APIController ...

中访问

我找到了https://github.com/JustMaier/Rotativa/tree/ed7678eefdffb3995f5b6a3e9afb18903c648df8 但它需要View

问题在方法BuildFile()...

从这里开始

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;
    }

我做错了什么?

2 个答案:

答案 0 :(得分:0)

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

如果您确实需要使用Rotativa,则可以尝试以下操作:

  • 添加一个虚拟视图,您可以使用ViewModel从数据库中将HTML传递给该虚拟视图
  • 创建一个虚拟上下文,如this question
  • 所示

答案 1 :(得分:0)

尝试一下: 来自API控制器(称为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;
        }
   }