html2pdf asp.net,pdf generation - Export html to pdf in ASP.NET Core - Stack Overflow

This is a solution working for ASP.NET Core 2.0, which allows either to generate dynamic PDF files from cshtml, directly send them to users and/or save them before sending.

To complement Jan Blaha answer there, for more flexibility, you may want to use the following code:

/// Generate a PDF from a html string

async Task GeneratePDFAsync(string htmlContent)

{

IJsReportFeature feature = new JsReportFeature(HttpContext);

feature.Recipe(Recipe.PhantomPdf);

if (!feature.Enabled) return (null, null);

feature.RenderRequest.Template.Content = htmlContent;

var report = await _RenderService.RenderAsync(feature.RenderRequest);

var contentType = report.Meta.ContentType;

MemoryStream ms = new MemoryStream();

report.Content.CopyTo(ms);

return (contentType, ms);

}

Using a class to render cshtml files as string, you may use the following service (which can be injected as a scoped service):

public class ViewToStringRendererService: ViewExecutor

{

private ITempDataProvider _tempDataProvider;

private IServiceProvider _serviceProvider;

public ViewToStringRendererService(

IOptions viewOptions,

IHttpResponseStreamWriterFactory writerFactory,

ICompositeViewEngine viewEngine,

ITempDataDictionaryFactory tempDataFactory,

DiagnosticSource diagnosticSource,

IModelMetadataProvider modelMetadataProvider,

ITempDataProvider tempDataProvider,

IServiceProvider serviceProvider)

: base(viewOptions, writerFactory, viewEngine, tempDataFactory, diagnosticSource, modelMetadataProvider)

{

_tempDataProvider = tempDataProvider;

_serviceProvider = serviceProvider;

}

public async Task RenderViewToStringAsync(string viewName, TModel model)

{

var context = GetActionContext();

if (context == null) throw new ArgumentNullException(nameof(context));

var result = new ViewResult()

{

ViewData = new ViewDataDictionary(

metadataProvider: new EmptyModelMetadataProvider(),

modelState: new ModelStateDictionary())

{

Model = model

},

TempData = new TempDataDictionary(

context.HttpContext,

_tempDataProvider),

ViewName = viewName,

};

var viewEngineResult = FindView(context, result);

viewEngineResult.EnsureSuccessful(originalLocations: null);

var view = viewEngineResult.View;

using (var output = new StringWriter())

{

var viewContext = new ViewContext(

context,

view,

new ViewDataDictionary(

metadataProvider: new EmptyModelMetadataProvider(),

modelState: new ModelStateDictionary())

{

Model = model

},

new TempDataDictionary(

context.HttpContext,

_tempDataProvider),

output,

new HtmlHelperOptions());

await view.RenderAsync(viewContext);

return output.ToString();

}

}

private ActionContext GetActionContext()

{

var httpContext = new DefaultHttpContext();

httpContext.RequestServices = _serviceProvider;

return new ActionContext(httpContext, new RouteData(), new ActionDescriptor());

}

///

/// Attempts to find the associated with .

///

/// The associated with the current request.

/// The .

/// A .

ViewEngineResult FindView(ActionContext actionContext, ViewResult viewResult)

{

if (actionContext == null)

{

throw new ArgumentNullException(nameof(actionContext));

}

if (viewResult == null)

{

throw new ArgumentNullException(nameof(viewResult));

}

var viewEngine = viewResult.ViewEngine ?? ViewEngine;

var viewName = viewResult.ViewName ?? GetActionName(actionContext);

var result = viewEngine.GetView(executingFilePath: null, viewPath: viewName, isMainPage: true);

var originalResult = result;

if (!result.Success)

{

result = viewEngine.FindView(actionContext, viewName, isMainPage: true);

}

if (!result.Success)

{

if (originalResult.SearchedLocations.Any())

{

if (result.SearchedLocations.Any())

{

// Return a new ViewEngineResult listing all searched locations.

var locations = new List(originalResult.SearchedLocations);

locations.AddRange(result.SearchedLocations);

result = ViewEngineResult.NotFound(viewName, locations);

}

else

{

// GetView() searched locations but FindView() did not. Use first ViewEngineResult.

result = originalResult;

}

}

}

if(!result.Success)

throw new InvalidOperationException(string.Format("Couldn't find view '{0}'", viewName));

return result;

}

private const string ActionNameKey = "action";

private static string GetActionName(ActionContext context)

{

if (context == null)

{

throw new ArgumentNullException(nameof(context));

}

if (!context.RouteData.Values.TryGetValue(ActionNameKey, out var routeValue))

{

return null;

}

var actionDescriptor = context.ActionDescriptor;

string normalizedValue = null;

if (actionDescriptor.RouteValues.TryGetValue(ActionNameKey, out var value) &&

!string.IsNullOrEmpty(value))

{

normalizedValue = value;

}

var stringRouteValue = routeValue?.ToString();

if (string.Equals(normalizedValue, stringRouteValue, StringComparison.OrdinalIgnoreCase))

{

return normalizedValue;

}

return stringRouteValue;

}

}

Then to conclude, in your controller, supposing the razor cshtml view template to be /Views/Home/PDFTemplate.cshtml you may use the following.

Note: The cshtml file may need to be copied when published (even if views are compiled).

var htmlContent = await _ViewToStringRendererService.RenderViewToStringAsync("Home/PDFTemplate", viewModel);

(var contentType, var generatedFile) = await GeneratePDFAsync(htmlContent);

Response.Headers["Content-Disposition"] = $"attachment; filename=\"{System.Net.WebUtility.UrlEncode(fileName)}\"";

// You may save your file here

using (var fileStream = new FileStream(Path.Combine(folder, fileName), FileMode.Create))

{

await generatedFile.CopyToAsync(fileStream);

}

// You may need this for re-use of the stream

generatedFile.Seek(0, SeekOrigin.Begin);

return File(generatedFile.ToArray(), "application/pdf", fileName);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值