MVC RazorでiTextSharp
を使用してHTMLをPDFに変換しようとしていますが、試してみたすべてが機能していません。
詳細な step-by-step tutorial
CodeProjectでフォローします。変換にiTextSharpを使用してASP.NET MVCビューをPDFファイルとして提供する方法を示しています。iTextSharpはHTMLをPDFそのため、複雑なHTMLページやCSSスタイルにうまく対応できない可能性があります。
Razorエンジン[〜#〜] not [〜#〜]奇妙な<itext..
マークアップ。
このようにして、標準のHTML出力を使用してPDFプレゼンテーションを完全に制御できます。
サンプルソリューションとソースコードを含むプロジェクトは、nugetのインストール手順とともにここから入手できます。
https://github.com/andyhutch77/MvcRazorToPdf
Install-Package MvcRazorToPdf
また、これは新しいitextsharpライセンスを使用するため、他の回答で言及されている否定の影響を受けません。
RazorPDF をチェックしてください。これは、iTextを使用してPDFを生成していますが、より使いやすい方法です。
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....
を渡すだけです
以下は、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;
}
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!
}
ASP.NET Coreを使用していて、iTextSharpがそれほど重要ではない場合は、PhantomJSを使用した私のソリューションがあります: http://nikolay.it/Blog/2018/03/Generate-PDF-file-from- Razor-view-using-ASP-NET-Core-and-PhantomJS/37
この手順は非常に簡単です。 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
メソッドを使用してビューを取得することが重要です。詳細情報 こちら 。
このタスクでは、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にアプリケーションをデプロイする場合は、UseShellExecute
をtrue
に設定することが重要です。
IViewRenderService
とIHtmlToPdfConverter
の両方を実装したので、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");
}
これは、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();
}
ここで、プレーンなxmlを作成する場合の別のアプローチを見つけることができます。
http://www.codeproject.com/Articles/260470/PDF-reporting-using-ASP-NET-MVC