Я использую wkhtmlToPdf (на самом деле rotativa), чтобы напечатать представление в формате pdf. Я успешно напечатал представление в формате PDF несколько раз. Но, как только он преуспел, он терпел неудачу как 10-50 раз, прежде чем снова работать Неважно, сколько данных в представлении или что-то еще. Чтобы это сработало в первый раз, мне также пришлось загрузить pdf 5 раз, прежде чем один из 5 действительно загрузился. Все остальное просто продолжает загружаться (один раз держал одну загрузку около 6 часов, ничего не делал).
Это код, где я вызываю метод ViewAsPdf
public IActionResult PrintPdf()
{
GraphsViewModel graphsView = new GraphsViewModel();
graphsView = HttpContext.Session.GetObjectSingle<GraphsViewModel>("graphsViewModel");
graphsView.PdfFormat = true;
return new Rotativa.AspNetCore.ViewAsPdf("GraphsPdf", graphsView) { CustomSwitches = "--no-stop-slow-scripts --window-status ready" };
}
метод вызывается во View следующим образом:
<div class="btn btn-default">
<a href="@Url.Action("PrintPdf", "Home")" target="_blank"><img src="~/images/pdf.png" width="40" /></a>
</div>
В представлении присутствуют некоторые тяжелые данные, но, как я уже сказал, если он работает один раз, почему он не работает каждый раз.
Заранее спасибо!
РЕДАКТИРОВАТЬ: код моего просмотра, это много, но большая часть этого - загружаемые диаграммы Google. Многое, вероятно, будет иметь мало смысла, поскольку у вас нет контекста к тем данным, которые я показываю, но это не очень важно для проблемы, с которой я сталкиваюсь.
@model project.Models.ViewModels.GraphsViewModel
@using project
@using project.Models
@using project.Models.Domain
@using project.Models.ViewModels
@{
string[] xas = Model.EfficiencyString;
double[] yas = Model.EfficiencyDouble;
List<string> impacts = Model.impacts;
List<string> urgenties = Model.urgenties;
int[,] Priorities = Model.prioriteiten;
List<string> categories = Model.Categories;
int[] NrPerCategory = Model.NrPerCategory;
List<string> uniqueGroups = Model.uniqueGroups;
List<string> allNames = Model.allNames;
MultiKeyDictionary<string, string, int> namesPerGroup = Model.namesPerGroup;
}
<head>
@{
ViewData["Title"] = "Graphs";
Layout = "~/Views/Shared/_LayoutGraphs.cshtml";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
//debugger;
// Load the Visualization API and the corechart package.
google.charts.load('current', { 'packages': ['corechart'] });
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawAmountPerCategory);
google.charts.setOnLoadCallback(drawIncNivStacked);
google.charts.setOnLoadCallback(drawIncNiv);
google.charts.setOnLoadCallback(drawEfficiency);
// Callback that creates and populates a data table,instantiates the pie chart, passes in the data and draws it.
function drawEfficiency() {
var data = new google.visualization.DataTable();
@{
@:data.addColumn('string', 'Status');
@:data.addColumn('number','Aantal');
for (var k = 0; k < @yas.Length; k++)
{
@:data.addRows([['@xas[k]',@yas[k]]]);
}
}
var options = {
'title': 'Aantal tickets in functie van de status',
'width': '1140',
'height': '200',
};
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
google.visualization.events.addListener(chart, 'ready', myReadyHandler);
chart.draw(data, options);
};
Category
function drawAmountPerCategory()
{
var data = new google.visualization.DataTable();
data.addColumn('string', 'Categorieën');
data.addColumn('number', 'Aantal');
data.addColumn({ type: 'number', role: 'annotation' })
@{
for (var c = 0; c < categories.Count(); c++)
{
if (!(NrPerCategory[c] == 0))
{
string categorie = categories[c];
@:data.addRows([['@categorie',@NrPerCategory[c],@NrPerCategory[c]]]);
}
}
}
var options = {
title: 'Aantal tickets per categorie',
'width': '1140',
'height': '200',
hAxis: {
title: 'Categorieën',
slantedText: true
},
chartArea: {
top: 28,
height: '40%',
width: '80%'
},
vAxis: {
title: 'Aantal'
},
legend: {position: 'none'}
};
data.sort([{ column: 1, desc: true }]);
var categorieChart = new google.visualization.ColumnChart(document.getElementById('cat_chart'));
categorieChart.draw(data, options);
}
function drawIncNiv()
{
var data = new google.visualization.DataTable();
data.addColumn('string', 'Soort incident');
data.addColumn('number', 'Aantal');
data.addColumn({ type: 'number', role: 'annotation' })
data.addRows([['P1',@Priorities[1, 1],@Priorities[1, 1]]]);
data.addRows([['P2',@Priorities[1, 2] + @Priorities[2, 1],@Priorities[1, 2] + @Priorities[2, 1]]]);
data.addRows([['P3',@Priorities[1, 3] + @Priorities[2, 2] + @Priorities[3, 1],@Priorities[1, 3] + @Priorities[2, 2] + @Priorities[3, 1]]]);
data.addRows([['P4',@Priorities[2, 3] + @Priorities[2, 4] + @Priorities[3, 2] + @Priorities[3, 3] + @Priorities[1, 4],@Priorities[2, 3] + @Priorities[2, 4] + @Priorities[3, 2] + @Priorities[3, 3] + @Priorities[1, 4]]]);
data.addRows([['P5',@Priorities[3, 4],@Priorities[3, 4]]]);
var options = {
title: 'Aantal tickets per Incident niveau',
'width': '1140',
'height': '200',
hAxis: {
title: 'Incident niveau',
},
vAxis: {
title: 'Aantal tickets'
},
chartArea: {
top: 28,
height: '40%',
width: '80%'
},
legend: { position: 'none' }
};
var categorieChart = new google.visualization.ColumnChart(document.getElementById('incniv_chart'));
categorieChart.draw(data, options);
}
function drawIncNivStacked()
{
var data = new google.visualization.DataTable();
data.addColumn('string', 'Impact');
data.addColumn('number', 'Unable to Work');
data.addColumn('number', 'Critical Business Process Unavailable');
data.addColumn('number', 'Normal Business Process Unavailable');
data.addColumn('number', 'Incident, but Workaround Available');
data.addColumn('number', 'Service Request');
data.addColumn('number', 'Not Set');
data.addColumn({ type: 'number', role: 'annotation' });
@{for (var m = 1; m < impacts.Count() + 1; m++)
{
int som = Priorities[m, 1] + Priorities[m, 2] + Priorities[m, 3] + Priorities[m, 4] + Priorities[m, 5] + Priorities[m, 6];
@:data.addRows([['@impacts[m - 1]', @Priorities[m, 1], @Priorities[m, 2], @Priorities[m, 3], @Priorities[m, 4], @Priorities[m, 5], @Priorities[m, 6], @som]]);
}
}
var options = {
title: 'Aantal tickets per Impact',
'width': '1140',
'height': '200',
isStacked: true,
vAxis: {
title: 'Aantal tickets'
},
chartArea: {
top: 28,
height: '70%',
width: '80%'
}
};
var categorieChart = new google.visualization.ColumnChart(document.getElementById('incnivStacked_chart'));
categorieChart.draw(data, options);
}
function CallBackForDrawingPdf() {
drawAmountPerCategory();
drawIncNivStacked();
drawIncNiv();
drawEfficiency();
}
function myReadyHandler() {
window.status = "ready";
}
</script>
</head>
<body onload="CallBackForDrawingPdf()">
<!-- Titel en de gekozen filter-->
@if (Model.PdfFormat == false) {
<h2>Graphs</h2>
<h3>@ViewBag.filter</h3>
<div class="btn btn-default">
<a href="@Url.Action("PrintPdf", "Home")" target="_blank"><img src="~/images/pdf.png" width="40" /></a>
</div>
}
<table class="table table-striped table-condensed table-bordered table-responsive table-hover">
<tr>
<th>Impact</th>
@{
foreach (var urg in urgenties)
{
<th>@urg</th>
}
}
</tr>
@{
int counter_imp = 1;
foreach (var mod in impacts)
{
int counter_urg = 1;
<tr>
<td>@mod</td>
@{
foreach (var urg in urgenties)
{
string value = @Priorities[counter_imp, counter_urg].ToString();
<td>@Html.ActionLink(value, "SlaFilter", new { imp = @impacts[counter_imp - 1], urg = @urgenties[counter_urg - 1] })</td>
counter_urg++;
}
counter_imp++;
}
</tr>
}
}
</table>
<div id="chartparent">
<!-- De div elementen bevatten elk een grafiek. De lijnen (hr) zijn puur voor wat overzicht op de pagina te creëren.-->
<hr style="width: 100%; color: black; height: 3px; background-color:dimgrey;" />
<div id="cat_chart"></div>
<div id="test_chart"></div>
<div id="incniv_chart"></div>
<div id="incnivStacked_chart"></div>
<div id="chart_div"></div>
<!-- De tabel waar per groep staat hoeveel tickets een persoon heeft behandeld.-->
<br />
<hr style="width: 100%; color: black; height: 3px; background-color:dimgrey;" />
</div>
<h4>PIVOT</h4>
<br />
@{
<table class="table table-condensed table-bordered table-responsive table-striped table-hover ">
@{int nr = 0;
int counter = 0;}
@{
// Overlopen van alle groepen
foreach (var gr in uniqueGroups)
{
string amount = "";
string id1 = ".group" + nr.ToString();
string id2 = "group" + nr.ToString();
foreach (var n in allNames)
{
if (namesPerGroup.ContainsKey(gr, n))
{
counter = counter + namesPerGroup[gr, n];
}
}
if (gr.Equals("NULL"))
{
<tr>
<th colspan="2" data-toggle="collapse" data-target="@id1" class="clickable danger">Not Set <b style="float: right;">@counter</b></th>
</tr>
}
else
{
<tr>
<th colspan="2" data-toggle="collapse" data-target="@id1" class="clickable info">@gr <b style="float: right;">@counter</b></th>
</tr>
}
foreach (var n in allNames)
{
if (namesPerGroup.ContainsKey(gr, n))
{
<tr>
<td class="collapse in @id2 "> <i>@n </i> <i style="float: right;">@amount </i></td>
</tr>
}
}
nr++;
counter = 0;
}
}
</table>
}
</body>