Вот мое решение для рендеринга области отчета моей страницы.
Ответ прост: опубликуйте html-контент раздела страницы, который я хочу отрендерить, на сервер, отредактируйте его в PDF и верните в виде файла для загрузки.
Для этого мне сначала нужно было получить html-контент для раздела страницы, содержащей отчет. Я сделал это, установив идентификатор div для моих отчетов в «report-content», а затем использовал некоторый скрипт для захвата этого html.
$(function () {
$("#btnSubmit").click(function () {
$("input[name='ReportContent']").val($("#report-content").html());
});
});
Форма для отправки запроса имеет скрытый элемент «ReportContent», в котором хранится html.
@using (Html.BeginForm("Export", "Home", FormMethod.Post))
{
<input type="hidden" name="ReportContent" />
<input type="submit" id="btnSubmit" value="Download PDF" />
}
На стороне сервера я создал метод, использующий API JsReport для рендеринга PDF из html.
protected async Task<IActionResult> RenderPDFAsync(string content)
{
var rs = new LocalReporting().UseBinary(JsReportBinary.GetBinary()).AsUtility().Create();
var report = await rs.RenderAsync(new RenderRequest()
{
Template = new Template()
{
Recipe = Recipe.ChromePdf,
Engine = Engine.None,
Content = content
}
});
return new FileStreamResult(report.Content, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/pdf"));
}
Наконец, я добавил обработчик для поста, который отображает PDF и возвращает результат файла на каждую страницу отчета.
public async Task<IActionResult> OnPostAsync()
{
return await RenderPDFAsync(Request.Form["ReportContent"].ToString());
}
Мой код имеет немного больше проверок, чем показано здесь, и у меня есть общий производный базовый класс PageModel для всех страниц моего отчета, поэтому единственное, что требуется для новых отчетов, - это добавление пост-хандера и установка идентификатора в разделе так, чтобы включены в PDF. Я также намерен переместить рендеринг в службу, чтобы он мог использоваться совместно, а не пересоздаваться при каждом создании отчета.