У меня есть динамически отфильтрованная таблица элементов, и у каждого есть группа кнопок для работы с ними. Один из них показывает частичный HTML, сгенерированный с помощью Razor с данными элемента.
Запись в таблице:
foreach (var item in listado.Where(x => x.Raw != null)) {
<tr>
<td>@item.Id</td>
<td>@item.Usuario</td>
<td>@item.NIF_CIF</td>
<td>
@if (!(String.IsNullOrEmpty(item.Telefono)) && !(String.IsNullOrWhiteSpace(item.Telefono))) {
@item.Telefono
} else {
@Html.Raw("No disponible")}
</td>
<td>@Math.Round(item.Raw.PrecioTotal).ToString("0.##") €</td>
<td>@item.FechaCreacion.ToShortDateString()</td>
<td class="btn-group-sm" role="group">
<button class="eliminar btn btn-secondary btn-danger" data-itemid="@item.Id">Eliminar</button>
<button class="convertirPDF btn btn-secondary btn-info" data-itemid="@item.Id">PDF</button>
<button class="detalles btn brn-secondary btn-info" data-itemid="@item.Id">Detalles</button></td>
</tr>
<tr id="vistaDetalles@(item.Id)" hidden>
<td colspan="7">
@Html.Partial("_PresupuestoFinal", item)
</td>
</tr> }
Элемент, с которым я хочу работать, генерируется в строке
@Html.Partial("_PresupuestoFinal", item)
Итак, с помощью jQuery я предоставляю функции этим кнопкам. Код кнопки 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
указывает на метод в моем контроллере.
EDIT
Вот мой метод контроллера по запросу:
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();
}
Скрипт не срабатывает.
2-е РЕДАКТИРОВАНИЕ
Итак, я получил больше информации об ошибке:
presupuestoHTML[toArray]
Это причина ошибки. Не знаю где или как.
3-е РЕДАКТИРОВАНИЕ
Хорошо, теперь я знаю, что проблема в скрипте, получающем нужный мне 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.
Я буду продолжать изучать это, надеюсь, это прояснит проблему.
2-е ОБНОВЛЕНИЕ
Я работал над этим, у меня все работает, кроме загрузки файла. Я объясню:
Вот скрипт, он попадает в метод контроллера с правильными данными.
$(".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), а не загружаемый файл. Я также пробовал другие варианты, такие как преобразование файла в байтовый массив и его потоковую передачу, но поскольку я не хочу сохранять файл, эта опция отбрасывается (функции требуют путь к файлу, который я не могу предоставить, поскольку файл не сохраняется, все еще в памяти). Все еще работаю над этим.