web-dev-qa-db-fra.com

Convertir HTML en PDF dans MVC avec iTextSharp dans MVC Razor

J'essaie de convertir HTML en PDF avec iTextSharp dans MVC Razor, mais tout ce que j'ai essayé n'a pas fonctionné. Est ce que quelqu'un sait comment accomplir cela?

18
Ravi

Il y a un code détaillé et step-by-step tutorial sur CodeProject que vous pourriez suivre. Il illustre comment vous pouvez servir une vue ASP.NET MVC en tant que fichier PDF à l'aide de iTextSharp pour la conversion. N'oubliez pas cependant qu'iTextSharp n'est pas destiné à la conversion de HTML en PDF, de sorte qu'il risque de ne pas très bien gérer les pages HTML complexes et les styles CSS.

3
Darin Dimitrov

Voici comment vous implémentez cette solution en utilisant le Razor engine NOT avec le balisage bizarre <itext...

De cette façon, vous avez un contrôle total sur la présentation pdf en utilisant une sortie HTML standard.

Le projet avec un exemple de solution et de code source est disponible ici avec les instructions d’installation de nuget:

https://github.com/andyhutch77/MvcRazorToPdf

Install-Package MvcRazorToPdf

Ceci utilise également la nouvelle licence itextsharp, ne souffre donc d'aucun des inconvénients mentionnés dans les autres réponses. 

34
hutchonoid

Vous devriez vérifier RazorPDF qui utilise iText pour générer le PDF, mais de manière plus conviviale.

4
Rosdi Kasim
public virtual void printpdf(string html)    
{
     String htmlText = html.ToString();
     Document document = new Document();
     string filePath = HostingEnvironment.MapPath("~/Content/Pdf/");
     PdfWriter.GetInstance(document, new FileStream(filePath + "\\pdf-"+Filename+".pdf", FileMode.Create));

     document.Open();    
     iTextSharp.text.html.simpleparser.HTMLWorker hw = new iTextSharp.text.html.simpleparser.HTMLWorker(document);       
     hw.Parse(new StringReader(htmlText));    
     document.Close();    
}

il suffit de passer html string au paramètre cette chaîne que vous obtiendrez par renderpartialview text = viewname....

4
Vinit Patel

Voici un exemple complet pour MVC Razor en C # utilisant le evo html en pdf pour .net pour convertir la vue MVC actuelle en PDF et envoyer le résultat PDF au navigateur pour téléchargement:

[HttpPost]
public ActionResult ConvertCurrentPageToPdf(FormCollection collection)
{
    object model = null;
    ViewDataDictionary viewData = new ViewDataDictionary(model);

    // The string writer where to render the HTML code of the view
    StringWriter stringWriter = new StringWriter();

    // Render the Index view in a HTML string
    ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, "Index", null);
    ViewContext viewContext = new ViewContext(
            ControllerContext,
            viewResult.View,
            viewData,
            new TempDataDictionary(),
            stringWriter
            );
    viewResult.View.Render(viewContext, stringWriter);

    // Get the view HTML string
    string htmlToConvert = stringWriter.ToString();

    // Get the base URL
    String currentPageUrl = this.ControllerContext.HttpContext.Request.Url.AbsoluteUri;
    String baseUrl = currentPageUrl.Substring(0, currentPageUrl.Length - "Convert_Current_Page/ConvertCurrentPageToPdf".Length);

    // Create a HTML to PDF converter object with default settings
    HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

    // Convert the HTML string to a PDF document in a memory buffer
    byte[] outPdfBuffer = htmlToPdfConverter.ConvertHtml(htmlToConvert, baseUrl);

    // Send the PDF file to browser
    FileResult fileResult = new FileContentResult(outPdfBuffer, "application/pdf");
    fileResult.FileDownloadName = "Convert_Current_Page.pdf";

    return fileResult;
}
2
EvoPdf

Un bon moyen de convertir MVC HTML View vers PDF (même si ce n'est pas directement sur le sujet concernant iTextSharp) utilise Rotativa :

Install-Package Rotativa

Ceci est basé sur wkhtmltopdf mais il offre un meilleur support CSS que iTextSharp et est très simple à intégrer à MVC car vous pouvez simplement retourner la vue au format pdf

public ActionResult GetPdf()
{
    //...
    return new ViewAsPdf(model);// and you are done!
}
2
meJustAndrew

Si vous utilisez ASP.NET Core et que iTextSharp n’est pas si important pour vous, voici ma solution utilisant PhantomJS: http://nikolay.it/Blog/2018/03/Generate-PDF-file-from-Razor- view-using-ASP-NET-Core-and-PhantomJS/37

Obtenir une chaîne HTML à partir d'une vue Razor

Cette étape est assez simple. Il existe un service appelé IRazorViewEngine dans ASP.NET Core qui peut être injecté puis utilisé pour obtenir la vue. Après avoir fourni la vue avec les valeurs par défaut ViewDataDictionary et ActionContext, nous pouvons demander que la vue soit rendue en StringWriter qui peut être facilement convertie en chaîne. Voici du code prêt à l'emploi pour obtenir une chaîne à partir d'un fichier de vue Razor donné:

public interface IViewRenderService
{
    Task<string> RenderToStringAsync(string viewName, object model);
}

public class ViewRenderService : IViewRenderService
{
    private readonly IRazorViewEngine razorViewEngine;
    private readonly ITempDataProvider tempDataProvider;
    private readonly IServiceProvider serviceProvider;

    public ViewRenderService(
        IRazorViewEngine razorViewEngine,
        ITempDataProvider tempDataProvider,
        IServiceProvider serviceProvider)
    {
        this.razorViewEngine = razorViewEngine;
        this.tempDataProvider = tempDataProvider;
        this.serviceProvider = serviceProvider;
    }

    public async Task<string> RenderToStringAsync(string viewName, object model)
    {
        var httpContext = new DefaultHttpContext { RequestServices = this.serviceProvider };
        var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

        using (var sw = new StringWriter())
        {
            var viewResult = this.razorViewEngine.GetView(null, viewName, false);

            if (viewResult.View == null)
            {
                throw new ArgumentNullException($"{viewName} does not match any available view");
            }

            var viewDictionary =
                new ViewDataDictionary(
                    new EmptyModelMetadataProvider(),
                    new ModelStateDictionary()) { Model = model };

            var viewContext = new ViewContext(
                actionContext,
                viewResult.View,
                viewDictionary,
                new TempDataDictionary(actionContext.HttpContext, this.tempDataProvider),
                sw,
                new HtmlHelperOptions());

            await viewResult.View.RenderAsync(viewContext);
            return sw.ToString();
        }
    }
}

Une chose importante à penser ici: si vous utilisez la compilation de vues (précompiler des vues avec YourProject.Web.PrecompiledViews.dll), il est important d’obtenir la vue en utilisant la méthode GetView au lieu de FindView. Plus d'informations ici .

Générez le fichier PDF à partir de HTML à l'aide de PhantomJS

Pour cette tâche, nous allons utiliser un navigateur sans interface graphique qui restituera le code HTML (avec tous les fichiers CSS et JS inclus). Il existe de nombreux outils de ce type, mais je vais utiliser PhantomJS (WebKit sans tête, scriptable avec une API JavaScript). PhantomJS peut enregistrer la page rendue au format PDF de petite taille assez rapidement. Pour que l’exportation PDF fonctionne, nous aurons besoin d’un fichier .js qui utilisera l’API PhantomJS pour indiquer à l’outil que nous souhaitons exporter le fichier:

"use strict";
var page = require('webpage').create(),
    system = require('system'),
    address,
    output;

console.log('Usage: rasterize.js [URL] [filename] [paperformat]');
address = system.args[1];
output = system.args[2];
page.viewportSize = { width: 600, height: 600 };
page.paperSize = { format: system.args[3], orientation: 'portrait', margin: '0.5cm' };

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit(1);
    } else {
        window.setTimeout(function () {
            page.render(output);
            phantom.exit();
        }, 200);
    }
});

La prochaine étape consiste à exécuter le processus phantomjs.exe et à transmettre le fichier rasterize.js ainsi que les chemins d'accès au fichier HTML et le nom du fichier de sortie pour le résultat PDF. Ceci est fait dans HtmlToPdfConverter.cs:

public interface IHtmlToPdfConverter
{
    byte[] Convert(string htmlCode);
}

public class HtmlToPdfConverter : IHtmlToPdfConverter
{
    public byte[] Convert(string htmlCode)
    {
        var inputFileName = "input.html";
        var outputFileName = "output.pdf";
        File.WriteAllText(inputFileName, htmlCode);
        var startInfo = new ProcessStartInfo("phantomjs.exe")
                            {
                                WorkingDirectory = Environment.CurrentDirectory,
                                Arguments = string.Format(
                                    "rasterize.js \"{0}\" {1} \"A4\"",
                                    inputFileName,
                                    outputFileName),
                                UseShellExecute = true,
                            };

        var process = new Process { StartInfo = startInfo };
        process.Start();

        process.WaitForExit();

        var bytes = File.ReadAllBytes(outputFileName);

        File.Delete(inputFileName);
        File.Delete(outputFileName);

        return bytes;
    }
}

Si vous souhaitez déployer votre application dans Azure, il est important que UseShellExecute soit défini sur true.

Utilisez le code ensemble

Puisque nous avons maintenant implémenté IViewRenderService et IHtmlToPdfConverter, nous pouvons commencer à les utiliser en les enregistrant d’abord dans le fichier Startup.cs où votre méthode ConfigureServices doit être située (services.AddScoped<IViewRenderService, ViewRenderService>() et services.AddScoped<IHtmlToPdfConverter, HtmlToPdfConverter>()). Voyons maintenant le code encapsulé ensemble:

private readonly IViewRenderService viewRenderService;
private readonly IHtmlToPdfConverter htmlToPdfConverter;

public DashboardController(
    IViewRenderService viewRenderService,
    IHtmlToPdfConverter htmlToPdfConverter)
{
    this.viewRenderService = viewRenderService;
    this.htmlToPdfConverter = htmlToPdfConverter;
}

[HttpGet]
public async Task<IActionResult> GetPdf(SomeInputModel input)
{
    var model = this.GetViewModel(input);
    var htmlData = await this.viewRenderService.RenderToStringAsync("~/Views/Dashboard/GetPdf.cshtml", model);
    var fileContents = this.htmlToPdfConverter.Convert(htmlData);
    return this.File(fileContents, "application/pdf");
}
0
Nikolay Kostov

Voici comment faire en utilisant MVC:

[Route("ABCDD")]
[HttpGet]
public void ABCDD() {
    WebClient wc = new WebClient();
    // string url = HttpContext.Current.Request.Url.AbsoluteUri;
    string url = "http://localhost:3042/Reports/COAListing";
    string fileContent = wc.DownloadString(url);

    List<string> tableContents = GetContents(fileContent, table_pattern);

    string HTMLString = String.Join(" ", tableContents.ToArray());

    Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
    PdfWriter.GetInstance(pdfDoc, HttpContext.Current.Response.OutputStream);
    pdfDoc.Open();
    pdfDoc.Add(new Paragraph("Welcome to dotnetfox"));
    List<IElement> htmlarraylist = HTMLWorker.ParseToList(new StringReader(HTMLString), null);
    for (int k = 0; k < htmlarraylist.Count; k++) {
        pdfDoc.Add((IElement) htmlarraylist[k]);
    }

    pdfDoc.Close();
    HttpContext.Current.Response.ContentType = "pdf/application";
    HttpContext.Current.Response.AddHeader("content-disposition", "attachment;" +
            "filename=sample.pdf");
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    HttpContext.Current.Response.Write(pdfDoc);
    HttpContext.Current.Response.End();
}
0
Vivek Shukla

ici, vous pouvez trouver une approche différente dans le cas où vous voudriez écrire du XML simple, je le trouve beaucoup plus simple et plus léger.

http://www.codeproject.com/Articles/260470/PDF-reporting-using-ASP-NET-MVC3

0
alexo