将Razor HTML转换为可下载的PDF

我有一个动态过滤的元素表,每个元素都有一组按钮来操作它们。 其中一个显示了使用Razor生成的部分HTML以及元素的数据。

表格条目:

foreach (var item in listado.Where(x => x.Raw != null)) {  @item.Id @item.Usuario @item.NIF_CIF  @if (!(String.IsNullOrEmpty(item.Telefono)) && !(String.IsNullOrWhiteSpace(item.Telefono))) { @item.Telefono } else { @Html.Raw("No disponible")}  @Math.Round(item.Raw.PrecioTotal).ToString("0.##") € @item.FechaCreacion.ToShortDateString()        @Html.Partial("_PresupuestoFinal", item)   } 

我想要使​​用的元素是在行中生成的

 @Html.Partial("_PresupuestoFinal", item) 

那么,使用jQuery,我为这些按钮提供了function。 PDF按钮代码是:

 $(".convertirPDF").on("click", function (id) { var itemId = $(this).data('itemid'); var presupuesto = $('#content').html($(this).find('#vistaDetalles' + itemId).html()); Pdf(presupuesto); }); function Pdf(presupuesto) { presupuestoHTML = presupuesto; $.ajax({ method: "GET", url: 'DescargarPDF', data: { presupuestoHTML: presupuesto }, cache: false, async: true, }); }; 

但每次按下按钮,我都会进入控制台:

 TypeError: can't convert undefined to object 

当我调用函数Pdf时参考该行。 我想要做的是选择特定的html(与元素对应的那个)并将其转换为PDF文件。 由于我无法获得足够的信息来了解错误的位置,我做错了什么?

顺便说一下url: 'DescargarPDF行指向我控制器中的方法。

编辑

这是我要求的控制器方法:

 public void DescargarPDF (string presupuestoHTML) { Response.Clear(); Response.ContentType = "application/pdf"; Response.AddHeader("content-disposition", "attachment;filename=" + "PDF.pdf"); Response.Cache.SetCacheability(HttpCacheability.NoCache); MemoryStream ms = new MemoryStream(); TextReader txtReader = new StringReader(presupuestoHTML); // Creamos un objeto de clase itextsharp document Document doc = new Document(PageSize.A4, 25, 25, 30, 30); // Creamos un pdfwriter de itextsharp que lee el documento y dirige un stream XML a un archivo PdfWriter oPdfWriter = PdfWriter.GetInstance(doc, ms); // Creamos un trabajador para parsear el documento HTMLWorker htmlWorker = new HTMLWorker(doc); // Abrimos el documento y se lo pasamos al trabajador doc.Open(); htmlWorker.StartDocument(); // Parseamos el presupuesto en html al documento htmlWorker.Parse(txtReader); // Cerramos el documento y el trabajador htmlWorker.EndDocument(); htmlWorker.Close(); doc.Close(); var bPDF = ms.ToArray(); Response.BinaryWrite(bPDF); Response.End(); } 

该脚本没有命中它。

第二次编辑

所以我得到了更多关于错误的信息:

 presupuestoHTML[toArray] 

是什么导致了错误。 不知道在哪里或如何。

第三次编辑

好的,所以我现在知道问题是在脚本上检索我想要的html。 我换了那条线:

 $(".convertirPDF").on("click", function (id) { itemId = $(this).data('itemid'); presupuesto = document.documentElement.getElementsByTagName('vistaDetalles' + itemId); Pdf(presupuesto); }); 

现在控制台中的错误是:

 TypeError: 'item' called on an object that does not implement interface HTMLCollection. 

我会继续调查,希望这会让问题更加清晰。

第二次更新

我一直在努力,除了文件下载之外,我得到了一切。 我会解释一下:

这是脚本,它使用适当的数据命中控制器方法。

 $(".convertirPDF").on("click", function (id) { var itemId = $(this).data('itemid'); // var presupuesto = $('#vistaDetalles' + itemId).html(); Pdf(itemId); }); function Pdf(itemid) { var id = itemid; $.ajax({ method: "POST", url: 'DescargarPDF', data: { itemId: id }, cache: false, async: true, }); }; 

这样才行。 这是我的控制器方法,我怀疑是由此引起的:

  public FileResult DescargarPDF (int itemId) { var presupuesto = ReglasNegocio.Fachada.Consultas.ObtenerPresupuesto(itemId); var archivo = new Rotativa.PartialViewAsPdf("_PresupuestoFinal", presupuesto) { FileName = "Presupuesto_" + itemId + ".pdf" }; return File(archivo.FileName, "application/pdf"); } 

这是我迄今为止的最后一次尝试。 我也尝试过Rotativa的ActionAsPdf ,我在浏览器控制台上获得了一个数据流(我猜它是pdf文件)而不是可下载的文件。 我还尝试了其他选项,比如将文件转换为字节数组并对其进行流式处理,但由于我不想保存文件,因此该选项被丢弃(函数需要文件路径,我无法提供,因为文件未保存,仍在内存中)。 仍在努力。

我问另一个问题 ,试图解决不下载文件问题,我明白了。

在此之前,我正在通过ajax做请求,因为我认为这是一个很好的方法,但事实certificate,有一个更简单的方法:不使用ajax。

所以,我删除了按钮和按钮本身的脚本,所以现在看起来像这样:

 PDF 

它具有与以前相同的外观,但它实际上是我的控制器方法的链接,现在看起来像这样:

 public FileResult DescargarPDF (int itemId) { var presupuesto = ReglasNegocio.Fachada.Consultas.ObtenerPresupuesto(itemId); var archivo = new Rotativa.PartialViewAsPdf("_PresupuestoFinal", presupuesto) { FileName = "Presupuesto_" + itemId + ".pdf", PageSize = Rotativa.Options.Size.A4 }; var binario = archivo.BuildFile(this.ControllerContext); return File(binario, "application/pdf", archivo.FileName); } 

我知道在大多数情况下这不是一个有效的解决方案,因为我只是留下了ajax,但还有许多其他问题,答案适用于他们,他们仍然使用ajax来管理请求。

不过,我希望这会有所帮助。 谢谢大家。 快乐的编码。

UPDATE

我刚刚发现为什么我的PDF文件被放入控制台,检查另一个问题 ,我为这个特定问题留了一点解释。 感谢大家。

你只能使用javascript:

  • 将您的HTML内容包装在div中并为其设置ID
  • 下载jsPDF
  • 请遵循以下示例: https ://rawgit.com/MrRio/jsPDF/master/(HTML RENDERER)