web-dev-qa-db-ja.com

MVC RazorのiTextSharpを使用してMVCでHTMLをPDFに変換

MVC RazorでiTextSharpを使用してHTMLをPDFに変換しようとしていますが、試してみたすべてが機能していません。

18
Ravi

詳細な step-by-step tutorial CodeProjectでフォローします。変換にiTextSharpを使用してASP.NET MVCビューをPDFファイルとして提供する方法を示しています。iTextSharpはHTMLをPDFそのため、複雑なHTMLページやCSSスタイルにうまく対応できない可能性があります。

3
Darin Dimitrov

Razorエンジン[〜#〜] not [〜#〜]奇妙な<itext..マークアップ。

このようにして、標準のHTML出力を使用してPDFプレゼンテーションを完全に制御できます。

サンプルソリューションとソースコードを含むプロジェクトは、nugetのインストール手順とともにここから入手できます。

https://github.com/andyhutch77/MvcRazorToPdf

Install-Package MvcRazorToPdf

また、これは新しいitextsharpライセンスを使用するため、他の回答で言及されている否定の影響を受けません。

34
hutchonoid

RazorPDF をチェックしてください。これは、iTextを使用してPDFを生成していますが、より使いやすい方法です。

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();    
}

renderpartialview html stringで取得する文字列のパラメーターにtext = viewname....を渡すだけです

4
Vinit Patel

以下は、C#でのMVC Razorの完全な例です。 。htmlの場合はhtmlからpdfへ を使用して、現在のMVCビューをPDFに変換し、結果のPDFをブラウザーに送信しますダウンロード:

[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

MVC HTML ViewからPDF(iTextSharpに関する主題に直接関係なくても)に変換する良い方法は、 Rotativa を使用することです:

Install-Package Rotativa

これはwkhtmltopdfに基づいていますが、iTextSharpよりも優れたcssサポートを持ち、ビューをpdfとして単純に返すことができるため、MVCとの統合が非常に簡単です。

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

ASP.NET Coreを使用していて、iTextSharpがそれほど重要ではない場合は、PhantomJSを使用した私のソリューションがあります: http://nikolay.it/Blog/2018/03/Generate-PDF-file-from- Razor-view-using-ASP-NET-Core-and-PhantomJS/37

RazorビューからHTML文字列を取得します

この手順は非常に簡単です。 ASP.NET CoreにはIRazorViewEngineというサービスがあり、これを挿入してからビューを取得するために使用できます。ビューにデフォルトのViewDataDictionaryおよびActionContextを提供した後、ビューをStringWriterにレンダリングするように要求できます。これは、文字列に簡単に変換できます。これは、指定されたRazorビューファイルから文字列を取得するためのすぐに使用できるコードです。

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();
        }
    }
}

ここで重要なのは、ビューのコンパイル(ビューをYourProject.Web.PrecompiledViews.dllにプリコンパイルする)を使用する場合、GetViewの代わりにFindViewメソッドを使用してビューを取得することが重要です。詳細情報 こちら

PhantomJSを使用してHTMLからPDFファイルを生成

このタスクでは、HTML(すべてのCSSとJSを含む)をレンダリングするヘッドレスブラウザーを使用します。このようなツールは多数ありますが、私は PhantomJS (JavaScript APIでスクリプト可能なヘッドレスWebKit)を使用します。 PhantomJSはレンダリングされたページを小さなサイズに保存することができますPDF非常に高速。PDFエクスポートするには、.jsファイルを使用する必要がありますファイルをエクスポートすることをツールに伝えるPhantomJS API:

"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);
    }
});

次は、phantomjs.exeプロセスを実行し、rasterize.jsファイルをHTMLファイルのパスとPDF結果の出力ファイル名とともに渡します。これは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;
    }
}

Azureにアプリケーションをデプロイする場合は、UseShellExecutetrueに設定することが重要です。

コードを一緒に使用する

IViewRenderServiceIHtmlToPdfConverterの両方を実装したので、ConfigureServicesメソッドを配置するStartup.csファイルに最初に登録することで、それらの使用を開始できます(services.AddScoped<IViewRenderService, ViewRenderService>()services.AddScoped<IHtmlToPdfConverter, HtmlToPdfConverter>())。ここで、一緒にまとめられたコードを見てみましょう。

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

これは、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

ここで、プレーンなxmlを作成する場合の別のアプローチを見つけることができます。

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

0
alexo