Search code examples
c#asp.netasp.net-core-webapidinktopdf

DinkToPdf including image in HtmlContent


I have a pdf invoice created using .Net Core 3 Web API and DinkToPdf library.

Now I need to insert into pdf an image as signature. I created the Resource folder of my project and add the image with the Copy to Output Directory set to allways. But I don't know how to use it in my string value which contain all the pdf data.

 var htmlDoc = new StringBuilder();
 ...
 htmlDoc.AppendLine("<td>");

 // here I need to insert the image
 Stream imgStream = Assembly.GetExecutingAssembly()
  .GetManifestResourceStream("Project.Resources.signature.jpeg"); // is allways null
 or
 htmlDoc.AppendLine("<img src=\"Project.Resources.signature.jpeg\" />");

 htmlDoc.AppendLine("</td>");

 var doc = new HtmlToPdfDocument()
 {
     GlobalSettings = {
         ColorMode = ColorMode.Color,
         Orientation = Orientation.Landscape,
         PaperSize = PaperKind.A4Plus,
         Margins = new MarginSettings() { Top = 10, Left = 30, Right = 30 }
     },
     Objects = {
         new ObjectSettings() {
             PagesCount = true,
             HtmlContent = htmlDoc.ToString(),
             WebSettings = { DefaultEncoding = "utf-8" }
         }
     }
 };

 var pdf = converter.Convert(doc);
 var stream = new MemoryStream(pdf);
 var contentType = @"application/pdf";
 var fileName = $"Invoice_{entity.Id}.pdf";
 stream.Seek(0, SeekOrigin.Begin);
 
 return File(stream, contentType, fileName);

Startup.cs:

services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

edit: I found absolute path works

 htmlDoc.AppendLine("<img src=\"C/User/Application/Project/Resources/signature.jpeg\" />");

But, this is not an optimal solution because the absolute path of local environment is different of production environment .

any other idea? thanks


Solution

  • The working directory of Asp.net Core is different from the web directory. You need to add the folder wwwroot in the project root directory. It is the root directory of the web.

    enter image description here

    In controller, get the project root directory through IWebHostEnvironment. Here is the example.

    [ApiController]
    [Route("dink/")]
    public class DinkController:ControllerBase
    {
        IConverter converter;
        public IConfiguration Configuration;
        IWebHostEnvironment webHostEnvironment;
        public DinkController(IConverter _converter,IConfiguration configuration,IWebHostEnvironment environment)
        {
            converter = _converter;
            Configuration = configuration;
            webHostEnvironment = environment;
        }
        //[Route("get")]
        public IActionResult get()
        {
            var htmlDoc = new StringBuilder();
            htmlDoc.AppendLine("<td>");
            var path = webHostEnvironment.WebRootPath+"\\1.png";//It fetches files under wwwroot
            htmlDoc.AppendLine($"<img src=\"{path}\" />");
            htmlDoc.AppendLine("</td>");
    
            var doc = new HtmlToPdfDocument()
            {
                GlobalSettings = {
                     ColorMode = ColorMode.Color,
                     Orientation = Orientation.Landscape,
                     PaperSize = PaperKind.A4Plus,
                     Margins = new MarginSettings() { Top = 10, Left = 30, Right = 30 }
                 },
                 Objects = {
                     new ObjectSettings() {
                         PagesCount = true,
                         HtmlContent = htmlDoc.ToString(),
                         WebSettings = { DefaultEncoding = "utf-8" }
                     }
                 }
            };
    
            var pdf = converter.Convert(doc);
            var stream = new MemoryStream(pdf);
            var contentType = @"application/pdf";
            var fileName = $"Invoice_Id.pdf";
            stream.Seek(0, SeekOrigin.Begin);
    
            return File(stream, contentType, fileName);
        }
    }