1

I have a MVC application and want to generate PDF using HTML. In here I use wkHTMLtoPdf exe to do my job.

I call to an action method from client side using jquery. Then it hit to below method.

public FileContentResult ExportInvoiceASPDF(string invno)
        {
            try
            {
                Byte[] bytes;                
                var fullUrl = this.Url.Action("pdfCustomerInvoice", "Report", new { invNo = invno }, Request.Url.Scheme);
                bytes = WKHtmlToPdf(fullUrl);

                FileContentResult result = new FileContentResult(bytes, "application/pdf")
                {
                    FileDownloadName = "PriceNotification"
                };
                return File(result.FileContents, "application/pdf");
            }
            catch (Exception ex)
            {

                throw;
            }
        }

In here I called to WKHtmlToPdf function for getting byte stream. (Below code extracted from stackoverflow thread)

public byte[] WKHtmlToPdf(string url_input)
        {
            try
            {
                var fileName = " - ";
                var wkhtmlDir = ConfigurationSettings.AppSettings["wkhtmlDir"];//Directory of wkHtmltopdf exe
                var wkhtml = ConfigurationSettings.AppSettings["wkhtml"];//wkhtmltopdf exe location
                var p = new Process();

                url = url_input;

                p.StartInfo.CreateNoWindow = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.FileName = wkhtml;
                p.StartInfo.WorkingDirectory = wkhtmlDir;

                string switches = "";
                switches += "--print-media-type ";
                switches += "--margin-top 10mm --margin-bottom 10mm --margin-right 10mm --margin-left 10mm ";
                switches += "--page-size Letter ";
                p.StartInfo.Arguments = switches + " " + url + " " + fileName;               
                p.Start();

                //read output
                byte[] buffer = new byte[32768];
                byte[] file;
                using (var ms = new MemoryStream())
                {
                    while (true)
                    {
                        int read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);

                        if (read <= 0)
                        {
                            break;
                        }
                        ms.Write(buffer, 0, read);
                    }
                    file = ms.ToArray();
                }

                // wait or exit
                p.WaitForExit(60000);

                // read the exit code, close process
                int returnCode = p.ExitCode;
                p.Close();

                return returnCode == 0 ? file : null;
            }
            catch (Exception ex)
            {

                // set your exceptions here
                return null;
            }
        }

Here I execute the view. (the page which I want to export as PDF)

public ActionResult pdfCustomerInvoice(string invNo)
        {
            var inv = _customerInvoiceService.GetCustomerInvoice(invNo);

            InvoiceSummaryReportsVM invRepVM = new InvoiceSummaryReportsVM();

           //My data assigning part going here

            return View(invRepVM);
        }

Here is pdfCustomerInvoice html.

@model Pro.Web.Models.ViewModels.InvoiceSummaryReportsVM

@{
    Layout = null;
}

<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">   
</head>
<body>

    <div class="center">
        <h2>Tax Invoice</h2>
    </div>

    <div class="row">
        <br />
        <br />
        <br />
        <br />
        <br />
    </div>

    <div class="row">
        <div class="col-md-6">

        </div>
        <div class="col-md-6">
            <div class="row">
                <div class="col-md-3">
                    @Html.LabelFor(model => model.InvoiceNo, htmlAttributes: new { @class = "control-label" })
                </div>
                <div class="col-md-3">
                    @Html.DisplayFor(model => model.InvoiceNo, new { htmlAttributes = new { @class = "form-control" } })
                </div>
            </div>


            <div class="row">
                <div class="col-md-3">
                    @Html.LabelFor(model => model.InvoiceDate, htmlAttributes: new { @class = "control-label" })
                </div>
                <div class="col-md-3">
                    @Html.DisplayFor(model => model.InvoiceDate, new { htmlAttributes = new { @class = "form-control" } })
                </div>
            </div>

            <div class="row">
                <div class="col-md-3">
                    @Html.LabelFor(model => model.AccountNo, htmlAttributes: new { @class = "control-label" })
                </div>
                <div class="col-md-3">
                    @Html.DisplayFor(model => model.AccountNo, new { htmlAttributes = new { @class = "form-control" } })
                </div>
            </div>

            <div class="row">
                <div class="col-md-3">
                    @Html.LabelFor(model => model.InvoiceStatementPeriod, htmlAttributes: new { @class = "control-label" })
                </div>
                <div class="col-md-3">
                    @Html.DisplayFor(model => model.InvoiceStatementPeriod, new { htmlAttributes = new { @class = "form-control" } })
                </div>
            </div>


        </div>

    </div>

    <div class="row">
        <div class="col-md-6">
            @Html.LabelFor(model => model.OpeningBalance, htmlAttributes: new { @class = "control-label" })
        </div>
        <div class="col-md-6">
            @Html.DisplayFor(model => model.OpeningBalance, new { htmlAttributes = new { @class = "form-control" } })
        </div>
    </div>

    <div class="row">
        <div class="col-md-6">
            @Html.LabelFor(model => model.InvoiceTotal, htmlAttributes: new { @class = "control-label" })
        </div>
        <div class="col-md-6">
            @Html.DisplayFor(model => model.InvoiceTotal, new { htmlAttributes = new { @class = "form-control" } })
        </div>
    </div>

    <div class="row">
        <div class="col-md-6">
            @Html.LabelFor(model => model.TaxAmount, htmlAttributes: new { @class = "control-label" })
        </div>
        <div class="col-md-6">
            @Html.DisplayFor(model => model.TaxAmount, new { htmlAttributes = new { @class = "form-control" } })
        </div>
    </div>

    <div class="row">
        <div class="col-md-6">
            @Html.LabelFor(model => model.TotalAmountPayable, htmlAttributes: new { @class = "control-label" })
        </div>
        <div class="col-md-6">
            @Html.DisplayFor(model => model.TotalAmountPayable, new { htmlAttributes = new { @class = "form-control" } })
        </div>
    </div>


</body>


</html>

The issue is when I execute the code, it is generated the PDF without styling. (All data align to left side.) But when I call to "pdfCustomerInvoice" method directly, the html comes properly with styling.

In here I have styling issue. Please give me a direction for fixing this problem.

1 Answer 1

3

It seems that bootstrap won't load then. Try to link bootstrap css from your file system.

For details: https://stackoverflow.com/a/20357784/6589639

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.