Creating PDF files in ASP.NET Core

微信扫一扫,分享到朋友圈

Creating PDF files in ASP.NET Core

This article shows how to create PDF files in ASP.NET Core. I decided I wanted to use PDFSharp, because I like this library, but no NuGet packages exist for .NET Standard 2.0. YetaWF created a port for this, which was used 1:1 in this example, without changes. It would be great to see PDFSharp as a .NET Standard 2.0 NuGet package.

Code: https://github.com/damienbod/AspNetCorePdf

Setting up the projects

To get the PDFSharp code working in ASP.NET Core, the best way is to clone the PDFsharp-.netcoreapp2.0 repository from YetaWF, and add this to your solution as a project. Then create an ASP.NET Core application, MVC or Razor Pages as preferred, and add a reference to the project.

Using the PDFSharp project

The example adds a HTTP Get request, creates a PdfData model which is used as an input for the PDF document. The PdfService was added as a scoped service to the IoC, and it creates the PDF document. This PDF document is then saved to the file system. The document is also returned in the HTTP response.

[HttpGet]
public FileStreamResult CreatePdf()
{
	var data = new PdfData
	{
		DocumentTitle = "This is my demo document Title",
		DocumentName = "myFirst",
		CreatedBy = "Damien",
		Description = "some data description which I have, and want to display in the PDF file..., This is another text, what is happening here, why is this text display...",
		DisplayListItems = new List
		{
			new ItemsToDisplay{ Id = "Print Servers", Data1= "some data", Data2 = "more data to display"},
			new ItemsToDisplay{ Id = "Network Stuff", Data1= "IP4", Data2 = "any left"},
			new ItemsToDisplay{ Id = "Job details", Data1= "too many", Data2 = "say no"},
			new ItemsToDisplay{ Id = "Firewall", Data1= "what", Data2 = "Let's burn it"}

		}
	};
	var path = _pdfService.CreatePdf(data);

	var stream = new FileStream(path, FileMode.Open);
	return File(stream, "application/pdf");
}

The PdfService implements one public method, CreatePdf which takes the model as a parameter. The path configurations are defined as private fields in the class. In a real application, these settings would be read from the app.settings. The method sets up the PDF document and pages using the PDFSharp project. Each part of the document is then created in different private methods.

using AspNetCorePdf.PdfProvider.DataModel;
using PdfSharp.Drawing;
using PdfSharp.Drawing.Layout;
using PdfSharp.Fonts;
using PdfSharp.Pdf;
using System;
using System.IO;

namespace AspNetCorePdf.PdfProvider
{
    public class PdfService : IPdfService
    {
        private string _createdDocsPath = ".\PdfProvider\Created";
        private string _imagesPath = ".\PdfProvider\Images";
        private string _resourcesPath = ".\PdfProvider\Resources";

        public string CreatePdf(PdfData pdfData)
        {
            if (GlobalFontSettings.FontResolver == null)
            {
                GlobalFontSettings.FontResolver = new FontResolver(_resourcesPath);
            }

            var document = new PdfDocument();
            var page = document.AddPage();
            var gfx = XGraphics.FromPdfPage(page);
    
            AddTitleLogo(gfx, page, $"{_imagesPath}\logo.jpg", 0, 0);
            AddTitleAndFooter(page, gfx, pdfData.DocumentTitle, document, pdfData);

            AddDescription(gfx, pdfData);

            AddList(gfx, pdfData);

            string docName = $"{_createdDocsPath}/{pdfData.DocumentName}-{DateTime.UtcNow.ToOADate()}.pdf";
            document.Save(docName);
            return docName;
        }

XGraphics is then used to create the document as required. Refer to the samples for reference:

http://www.pdfsharp.net/wiki/PDFsharpSamples.ashx

void AddTitleLogo(XGraphics gfx, PdfPage page, string imagePath, int xPosition, int yPosition)
{
	if (!File.Exists(imagePath))
	{
		throw new FileNotFoundException(String.Format("Could not find image {0}.", imagePath));
	}

	XImage xImage = XImage.FromFile(imagePath);
	gfx.DrawImage(xImage, xPosition, yPosition, xImage.PixelWidth / 8, xImage.PixelWidth / 8);
}

void AddTitleAndFooter(PdfPage page, XGraphics gfx, string title, PdfDocument document, PdfData pdfData)
{
	XRect rect = new XRect(new XPoint(), gfx.PageSize);
	rect.Inflate(-10, -15);
	XFont font = new XFont("OpenSans", 14, XFontStyle.Bold);
	gfx.DrawString(title, font, XBrushes.MidnightBlue, rect, XStringFormats.TopCenter);

	rect.Offset(0, 5);
	font = new XFont("OpenSans", 8, XFontStyle.Italic);
	XStringFormat format = new XStringFormat();
	format.Alignment = XStringAlignment.Near;
	format.LineAlignment = XLineAlignment.Far;
	gfx.DrawString("Created by " + pdfData.CreatedBy, font, XBrushes.DarkOrchid, rect, format);

	font = new XFont("OpenSans", 8);
	format.Alignment = XStringAlignment.Center;
	gfx.DrawString(document.PageCount.ToString(), font, XBrushes.DarkOrchid, rect, format);

	document.Outlines.Add(title, page, true);
}

void AddDescription(XGraphics gfx, PdfData pdfData)
{
	var font = new XFont("OpenSans", 14, XFontStyle.Regular);
	XTextFormatter tf = new XTextFormatter(gfx);
	XRect rect = new XRect(40, 100, 520, 100);
	gfx.DrawRectangle(XBrushes.White, rect);
	tf.DrawString(pdfData.Description, font, XBrushes.Black, rect, XStringFormats.TopLeft);
}

void AddList(XGraphics gfx, PdfData pdfData)
{
	int startingHeight = 200;
	int listItemHeight = 30;

	for (int i = 0; i < pdfData.DisplayListItems.Count; i++)
	{
		var font = new XFont("OpenSans", 14, XFontStyle.Regular);
		XTextFormatter tf = new XTextFormatter(gfx);
		XRect rect = new XRect(60, startingHeight, 500, listItemHeight);
		gfx.DrawRectangle(XBrushes.White, rect);
		var data = $"{i}. {pdfData.DisplayListItems[i].Id} | {pdfData.DisplayListItems[i].Data1} | {pdfData.DisplayListItems[i].Data2}";
		tf.DrawString(data, font, XBrushes.Black, rect, XStringFormats.TopLeft);

		startingHeight = startingHeight + listItemHeight;
	}
}

When the application is run, the create PDF link can be clicked, and it creates the PDF.

The PDF is returned in the browser. Each PDF can also be viewed in the Created directory.

This works really good, with little effort to setup. The used PDFSharp code is included in the repository. The MigraDoc is not part of this, it would be nice to use this as well, but no solution exists, which works for ASP.NET Core.

I really hope the the PDFSharp NuGet package as well as MigraDoc gets ported to .NET Core.

Links:

https://github.com/YetaWF/PDFsharp-.netcoreapp2.0

http://www.pdfsharp.net/wiki/Graphics-sample.ashx

http://www.pdfsharp.net/wiki/PDFsharpSamples.ashx

http://www.pdfsharp.net/

微信扫一扫,分享到朋友圈

Creating PDF files in ASP.NET Core

Users can now pay Litecoin through SMS, CoinText adds supports for Litecoin & Dash

上一篇

Facebook Open Sources LogDevice - a Distributed Data Store for Log Storage

下一篇

你也可能喜欢

Creating PDF files in ASP.NET Core

长按储存图像,分享给朋友