Skip to content

Commit

Permalink
[+] Added custom pdf size for puppeteer
Browse files Browse the repository at this point in the history
  • Loading branch information
SolidProgramming committed Sep 12, 2024
1 parent 1e9ef5b commit ed5ac52
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 33 deletions.
18 changes: 18 additions & 0 deletions roles/lib/files/FWO.Report/PaperFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace FWO.Report
{
public enum PaperFormat
{
A0,
A1,
A2,
A3,
A4,
A5,
A6,
Letter,
Legal,
Tabloid,
Ledger,
Custom
}
}
49 changes: 37 additions & 12 deletions roles/lib/files/FWO.Report/ReportBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
using System.Text;
using PuppeteerSharp.Media;
using PuppeteerSharp;
using System.Reflection;

namespace FWO.Report
{
public enum RsbTab
{
all = 10,
report = 20,
all = 10,
report = 20,
rule = 30,

usedObj = 40,
Expand All @@ -22,8 +23,8 @@ public enum RsbTab
public enum ObjCategory
{
all = 0,
nobj = 1,
nsrv = 2,
nobj = 1,
nsrv = 2,
user = 3
}

Expand All @@ -43,7 +44,7 @@ public enum OutputLocation

public abstract class ReportBase
{
protected StringBuilder HtmlTemplate = new ($@"
protected StringBuilder HtmlTemplate = new($@"
<!DOCTYPE html>
<html>
<head>
Expand Down Expand Up @@ -87,9 +88,11 @@ public abstract class ReportBase
protected UserConfig userConfig;
public ReportType ReportType;
public ReportData ReportData = new();
public int CustomWidth = 0;
public int CustomHeight = 0;

protected string htmlExport = "";

public bool GotObjectsInReport { get; protected set; } = false;


Expand Down Expand Up @@ -159,14 +162,14 @@ protected string GenerateHtmlFrameBase(string title, string filter, DateTime dat
HtmlTemplate = HtmlTemplate.Replace("##Filter##", userConfig.GetText("filter") + ": " + filter);
HtmlTemplate = HtmlTemplate.Replace("##GeneratedOn##", userConfig.GetText("generated_on"));
HtmlTemplate = HtmlTemplate.Replace("##Date##", date.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK"));
if(ReportType.IsChangeReport())
if (ReportType.IsChangeReport())
{
string timeRange = $"{userConfig.GetText("change_time")}: " +
$"{userConfig.GetText("from")}: {ToUtcString(Query.QueryVariables["start"]?.ToString())}, " +
$"{userConfig.GetText("until")}: {ToUtcString(Query.QueryVariables["stop"]?.ToString())}";
HtmlTemplate = HtmlTemplate.Replace("##Date-of-Config##: ##GeneratedFor##", timeRange);
}
else if(ReportType.IsRuleReport() || ReportType == ReportType.Statistics)
else if (ReportType.IsRuleReport() || ReportType == ReportType.Statistics)
{
HtmlTemplate = HtmlTemplate.Replace("##Date-of-Config##", userConfig.GetText("date_of_config"));
HtmlTemplate = HtmlTemplate.Replace("##GeneratedFor##", ToUtcString(Query.ReportTimeString));
Expand All @@ -185,7 +188,7 @@ protected string GenerateHtmlFrameBase(string title, string filter, DateTime dat
HtmlTemplate = HtmlTemplate.Replace("<p>##OwnerFilters##</p>", "");
}

if(deviceFilter != null)
if (deviceFilter != null)
{
HtmlTemplate = HtmlTemplate.Replace("##OtherFilters##", userConfig.GetText("devices") + ": " + deviceFilter);
}
Expand All @@ -205,13 +208,13 @@ public static string ToUtcString(string? timestring)
{
return timestring != null ? DateTime.Parse(timestring).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK") : "";
}
catch(Exception)
catch (Exception)
{
return timestring ?? "";
}
}

private static async Task<string?> CreatePDFViaPuppeteer(string html, PaperFormat format)
private async Task<string?> CreatePDFViaPuppeteer(string html, PaperFormat format)
{
using IBrowser? browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Expand All @@ -223,7 +226,9 @@ public static string ToUtcString(string? timestring)
using IPage page = await browser.NewPageAsync();
await page.SetContentAsync(html);

PdfOptions pdfOptions = new PdfOptions() { DisplayHeaderFooter = true, Landscape = true, PrintBackground = true, Format = format, MarginOptions = new MarginOptions { Top = "1cm", Bottom = "1cm", Left = "1cm", Right = "1cm" } };
PuppeteerSharp.Media.PaperFormat? pupformat = GetPuppeteerPaperFormat(format) ?? throw new Exception();

PdfOptions pdfOptions = new() { DisplayHeaderFooter = true, Landscape = true, PrintBackground = true, Format = pupformat, MarginOptions = new MarginOptions { Top = "1cm", Bottom = "1cm", Left = "1cm", Right = "1cm" } };
byte[] pdfData = await page.PdfDataAsync(pdfOptions);

return Convert.ToBase64String(pdfData);
Expand All @@ -238,6 +243,26 @@ public static string ToUtcString(string? timestring)
}
}

private PuppeteerSharp.Media.PaperFormat? GetPuppeteerPaperFormat(PaperFormat format)
{
if (format == PaperFormat.Custom)
return new PuppeteerSharp.Media.PaperFormat(CustomWidth, CustomHeight);

PropertyInfo[] propertyInfos = typeof(PuppeteerSharp.Media.PaperFormat).GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);

PropertyInfo? prop = propertyInfos.SingleOrDefault(_ => _.Name == format.ToString());

if (prop == null)
return default;

PuppeteerSharp.Media.PaperFormat? propFormat = (PuppeteerSharp.Media.PaperFormat)prop.GetValue(null);

if (propFormat is null)
return default;

return propFormat;
}

public virtual async Task<string?> ToPdf(string html, PaperFormat format)
{
return await CreatePDFViaPuppeteer(html, format);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ private async Task<MailData> PrepareEmail()
body += changeReport?.ExportToHtml();
break;
case (int)ImpChangeNotificationType.PdfAsAttachment:
string? pdfData = await changeReport.ToPdf(PaperFormat.A4);
string? pdfData = await changeReport.ToPdf(Report.PaperFormat.A4);

if (string.IsNullOrWhiteSpace(pdfData))
throw new Exception("No Pdf generated.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ private static async Task WriteReportFile(ReportBase report, List<FileFormat> fi
break;

case GlobalConst.kPdf:
reportFile.Pdf = await report.ToPdf(PaperFormat.A4);
reportFile.Pdf = await report.ToPdf(Report.PaperFormat.A4);
break;

case GlobalConst.kJson:
Expand Down
48 changes: 29 additions & 19 deletions roles/ui/files/FWO.UI/Pages/Reporting/ReportExport.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@using System.Text
@using FWO.Report
@using FWO.Config.Api
@using System.Reflection
@using WkHtmlToPdfDotNet
@using System.Linq
@using FWO.Report.Filter
Expand All @@ -10,8 +11,10 @@
@inject ApiConnection apiConnection
@inject UserConfig userConfig

<button type="button" class="btn btn-sm btn-dark" @onclick='() => { if (ReportToExport != null) { ShowExportDialog = true; reportExportFile = new ReportFile { Name = "Report", OwnerId = userConfig.User.DbId }; } else {
DisplayMessageInUi(null, userConfig.GetText("export_report"), userConfig.GetText("E1002"), true); } }'>@userConfig.GetText("export_report")</button>
<button type="button" class="btn btn-sm btn-dark" @onclick='() => { if (ReportToExport != null) { ShowExportDialog = true; reportExportFile = new ReportFile { Name = "Report", OwnerId = userConfig.User.DbId }; } else {
DisplayMessageInUi(null, userConfig.GetText("export_report"), userConfig.GetText("E1002"), true); } }'>
@userConfig.GetText("export_report")
</button>

<PopUp Title="@(userConfig.GetText("export_report"))" Show="@ShowExportDialog" Size=PopupSize.Small OnClose="() => ShowExportDialog = false">
<Body>
Expand All @@ -35,20 +38,20 @@
{
<div>
@(userConfig.GetText("page_format")):
<Dropdown @bind-SelectedElement="SelectedPaperKind" Elements="Enum.GetValues<PaperKind>().Cast<PaperKind>()"></Dropdown>
@if (SelectedPaperKind == PaperKind.Custom)
<Dropdown @bind-SelectedElement="SelectedPaperFormat" Elements="Enum.GetValues<PaperFormat>()"></Dropdown>
@if (SelectedPaperFormat == PaperFormat.Custom)
{
<div class="input-group input-group-sm mb-2 mt-2">
<div class="input-group-prepend">
<span class="input-group-text">@(userConfig.GetText("width"))</span>
</div>
<input @bind="PaperSizeWidth" min="1" max="1000000" type="number" class="form-control">
<div class="input-group-prepend">
<span class="input-group-text">@(userConfig.GetText("width"))</span>
</div>
<input @bind="PaperSizeWidth" min="1" max="1000000" type="number" class="form-control">
</div>
<div class="input-group input-group-sm mb-1">
<div class="input-group-prepend">
<span class="input-group-text">@(userConfig.GetText("height"))</span>
</div>
<input @bind="PaperSizeHeight" min="1" max="1000000" type="number" class="form-control">
<div class="input-group-prepend">
<span class="input-group-text">@(userConfig.GetText("height"))</span>
</div>
<input @bind="PaperSizeHeight" min="1" max="1000000" type="number" class="form-control">
</div>
}
</div>
Expand All @@ -65,7 +68,7 @@
{
<input class="form-check-input" type="checkbox" id="reportExportCsv" @bind="ExportCsv">
}
else
else
{
ExportCsv = false;
<input disabled class="form-check-input" type="checkbox" id="reportExportCsv">
Expand Down Expand Up @@ -94,11 +97,13 @@
</div>
</Body>
<Footer>
@if (!Exporting) {
@if (!Exporting)
{
<button type="button" class="btn btn-sm btn-primary" @onclick="async () => { Exporting = true; await Export(); ShowExportDialog = false; ShowExportDownloadDialog = true; Exporting = false; }">@(userConfig.GetText("export"))</button>
<button type="button" class="btn btn-sm btn-secondary" @onclick="() => ShowExportDialog = false">@(userConfig.GetText("cancel"))</button>
}
else {
else
{
<div class="spinner-border" role="status">
<span class="visually-hidden">Exporting...</span>
</div>
Expand All @@ -107,7 +112,7 @@
</PopUp>

<ReportDownloadPopUp Title="@(userConfig.GetText("export_report_download"))" ReportFile="reportExportFile"
Show="ShowExportDownloadDialog" ShowJson="ExportJson" OnClose="() => ShowExportDownloadDialog = false" />
Show="ShowExportDownloadDialog" ShowJson="ExportJson" OnClose="() => ShowExportDownloadDialog = false" />

@code
{
Expand All @@ -123,7 +128,7 @@
private bool ExportCsv = false;
private bool ExportArchive = false;
private ReportFile reportExportFile = new ReportFile();
private PaperKind SelectedPaperKind = PaperKind.A4;
private PaperFormat SelectedPaperFormat = PaperFormat.A4;

private bool ShowExportDialog = false;
private bool ShowExportDownloadDialog = false;
Expand All @@ -133,6 +138,8 @@
private int PaperSizeWidth = 0;
private int PaperSizeHeight = 0;



private bool csvAvailable()
{
return ReportToExport?.ReportType.IsResolvedReport() ?? false;
Expand Down Expand Up @@ -161,9 +168,12 @@
}

if (ExportPdf)
{
{
ReportToExport.CustomHeight = PaperSizeHeight;
ReportToExport.CustomWidth = PaperSizeWidth;

string html = ReportToExport.ExportToHtml();
reportExportFile.Pdf = await ReportToExport.ToPdf(html);
reportExportFile.Pdf = await ReportToExport.ToPdf(html, SelectedPaperFormat);
}

if (ExportCsv)
Expand Down

0 comments on commit ed5ac52

Please sign in to comment.