использование wkhtmlToPdf в большинстве случаев дает сбой (зависает при загрузке), но успешно выполняется один раз в 10 раз - PullRequest
0 голосов
/ 30 апреля 2018

Я использую 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>

1 Ответ

0 голосов
/ 30 апреля 2018

Вы можете использовать window.status как лучший индикатор для wkhtmltopdf.

На вашей странице вы можете поместить это, когда знаете, что страница готова (документ готов, если вы используете jquery или window.addEventListener("load")

window.status = "ReadyToPrint";

Затем вы можете упростить ваши аргументы wkhtmltopdf:

"--no-stop-slow-scripts --window-status ReadyToPrint"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...