Skia

Skia is an open source 2D graphics library which provides common APIs that work across a variety of hardware and software platforms.

It's able to generate PDF files with version 1.4. Header and tail for a PDF file is usually %PDF-1.4 and %EOF.

SkiaSharp dotnetcore

Library wrapper to use Skia in a dotnet core environment,

   1 dotnet add package SkiaSharp --version 1.57.1
   2 dotnet add package Avalonia.Skia.Linux.Natives --version 1.57.1.4
   3 
   4 # Install in docker container
   5 apt-get install -y libfontconfig1 
   6 
   7 # begin page SkDocument
   8 #end page SkDocument
   9 # end page SkDocument
  10 # close SkDocument
  11 # flush SkFileWStream
  12 # dispose SkFileWStream
  13 

Example controller to generate PDF

   1 using System;
   2 using System.IO;
   3 using System.Threading.Tasks;
   4 using Microsoft.AspNetCore.Mvc;
   5 using Microsoft.Extensions.Logging;
   6 using SkiaSharp;
   7 using System.Net.Mime;
   8 
   9 namespace test_webapi.Controllers
  10 {
  11     [ApiController]
  12     [Route("[controller]")]
  13     public class PdfController : ControllerBase
  14     {
  15         private readonly ILogger<PdfController> _logger;
  16 
  17         public PdfController(ILogger<PdfController> logger)
  18         {
  19             _logger = logger;
  20         }
  21 
  22         [HttpGet]
  23         [Route("[controller]/[action]/{title}")]
  24         public async Task<FileResult> CreatePdf(string title)
  25         {
  26             /*
  27             Adapted from https://github.com/mono/SkiaSharp/blob/master/samples/Gallery/Shared/Samples/CreatePdfSample.cs
  28             */
  29             var metadata = new SKDocumentPdfMetadata
  30             {
  31                 Author = "Cool Developer",
  32                 Creation = DateTime.Now,
  33                 Creator = "Cool Developer Library",
  34                 Keywords = "SkiaSharp, Sample, PDF, Developer, Library",
  35                 Modified = DateTime.Now,
  36                 Producer = "SkiaSharp",
  37                 Subject = "SkiaSharp Sample PDF",
  38                 Title = title,
  39             };
  40             var millisSinceDawnTime = DateTime.Now.Ticks / 10000;
  41             var filePath = $"{Path.GetTempPath()}{millisSinceDawnTime}_test.pdf";
  42             using (var stream = new SKFileWStream(filePath))
  43             using (var document = SKDocument.CreatePdf(stream, metadata))
  44             using (var paint = new SKPaint())
  45             {
  46                 paint.TextSize = 64.0f;
  47                 paint.IsAntialias = true;
  48                 paint.Color = (SKColor)0xFF9CAFB7;
  49                 paint.IsStroke = true;
  50                 paint.StrokeWidth = 3;
  51                 paint.TextAlign = SKTextAlign.Center;
  52 
  53                 // var width = 840;
  54                 // var height = 1188;
  55                 // Portrait a4 in pts units. 1 pt = 127/360mm
  56                 // https://en.wikipedia.org/wiki/Paper_size
  57                 // https://skia-doc.commondatastorage.googleapis.com/doxygen/doxygen/html/classSkDocument.html
  58                 var width = 595;
  59                 var height = 842;
  60 
  61                 // draw page 1
  62                 using (var pdfCanvas = document.BeginPage(width, height))
  63                 {
  64                     // draw button
  65                     var nextPagePaint = new SKPaint
  66                     {
  67                         IsAntialias = true,
  68                         TextSize = 16,
  69                         Color = SKColors.OrangeRed
  70                     };
  71                     var nextText = "Next Page >>";
  72                     var btn = new SKRect(width - nextPagePaint.MeasureText(nextText) - 24, 0, width, nextPagePaint.TextSize + 24);
  73                     pdfCanvas.DrawText(nextText, btn.Left + 12, btn.Bottom - 12, nextPagePaint);
  74                     // make button link
  75                     pdfCanvas.DrawLinkDestinationAnnotation(btn, "next-page");
  76 
  77                     // draw contents
  78                     pdfCanvas.DrawText("...PDF 1/2...", width / 2, height / 4, paint);
  79                     document.EndPage();
  80                 }
  81 
  82                 // draw page 2
  83                 using (var pdfCanvas = document.BeginPage(width, height))
  84                 {
  85                     // draw link destintion
  86                     pdfCanvas.DrawNamedDestinationAnnotation(SKPoint.Empty, "next-page");
  87 
  88                     // draw contents
  89                     pdfCanvas.DrawText("...PDF 2/2...", width / 2, height / 4, paint);
  90                     document.EndPage();
  91                 }
  92 
  93                 // end the doc
  94                 document.Close();
  95             }
  96             //var mimeType = "application/pdf";
  97             var mimeType = MediaTypeNames.Application.Pdf;
  98 
  99             Task<byte[]> fileBytes = System.IO.File.ReadAllBytesAsync(filePath);
 100             await fileBytes;
 101             return File(fileBytes.Result, mimeType, $"{millisSinceDawnTime}_test.pdf");
 102         }
 103     }
 104 }

Skia (last edited 2020-04-25 21:13:16 by localhost)