183 lines
7.7 KiB
C#
183 lines
7.7 KiB
C#
using Elwig.Windows;
|
|
using iText.Html2pdf;
|
|
using iText.Kernel.Pdf;
|
|
using iText.Kernel.Pdf.Event;
|
|
using iText.Kernel.Utils;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing.Printing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
|
|
namespace Elwig.Helpers.Printing {
|
|
public static class Pdf {
|
|
public static Task Init(Action? evtHandler = null) {
|
|
PdfiumNative.FPDF_InitLibrary();
|
|
evtHandler?.Invoke();
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public static Task Cleanup() {
|
|
PdfiumNative.FPDF_DestroyLibrary();
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public static (int Pages, IEnumerable<int> PerDoc) Convert(string htmlPath, string pdfPath, Documents.Document? doc = null) {
|
|
int nPages;
|
|
using var html = File.Open(htmlPath, FileMode.Open);
|
|
using var writer = new PdfWriter(pdfPath);
|
|
using var pdf = new PdfDocument(writer);
|
|
var footerHandler = new FooterEventHandler(doc);
|
|
pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, footerHandler);
|
|
pdf.AddEventHandler(PdfDocumentEvent.START_DOCUMENT_CLOSING, footerHandler);
|
|
// TODO embed fonts?
|
|
//pdf.AddFont(PdfFontFactory.CreateFont(StandardFonts.TIMES_ROMAN));
|
|
HtmlConverter.ConvertToPdf(html, pdf);
|
|
nPages = footerHandler.NumberOfPages;
|
|
return (nPages, [nPages]);
|
|
}
|
|
|
|
public static (int Pages, IEnumerable<int> PerDoc) Convert(IEnumerable<string> inputFiles, string pdfPath, bool doublePaged = false, IEnumerable<Documents.Document>? docs = null, CancellationToken? cancelToken = null, IProgress<double>? progress = null) {
|
|
var tmpFileNames = new List<string>();
|
|
var pageNums = new List<int>();
|
|
var tmpPageNums = new List<int>();
|
|
|
|
var htmlFiles = inputFiles
|
|
.Where(f => !f.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
|
|
.Select(f => f.TrimStart('!', '#'))
|
|
.ToList();
|
|
|
|
try {
|
|
for (int i = 0; i < htmlFiles.Count; i++) {
|
|
string tmpFile = $"{pdfPath}.{i:0000}.part";
|
|
tmpFileNames.Add(tmpFile);
|
|
var (pages, _) = Convert(htmlFiles[i], tmpFile, docs?.ElementAt(i));
|
|
tmpPageNums.Add(pages);
|
|
}
|
|
|
|
using var writer = new PdfWriter(pdfPath);
|
|
using var mergedPdf = new PdfDocument(writer);
|
|
var merger = new PdfMerger(mergedPdf);
|
|
|
|
PdfPage? letterheadPage = null;
|
|
int letterheadInsertIndex = 0;
|
|
int letterheadDocIndex = 0;
|
|
|
|
for (int i = 0; i < inputFiles.Count(); i++) {
|
|
var fileName = inputFiles.ElementAt(i);
|
|
int p0 = mergedPdf.GetNumberOfPages();
|
|
|
|
if (letterheadPage != null && fileName.StartsWith('#')) {
|
|
if (mergedPdf.GetNumberOfPages() <= letterheadInsertIndex) {
|
|
mergedPdf.AddPage(letterheadPage.CopyTo(mergedPdf));
|
|
mergedPdf.AddNewPage();
|
|
} else {
|
|
mergedPdf.AddPage(letterheadInsertIndex + 1, letterheadPage.CopyTo(mergedPdf));
|
|
mergedPdf.AddNewPage(letterheadInsertIndex + 2);
|
|
}
|
|
|
|
pageNums[letterheadDocIndex] = 1;
|
|
letterheadPage = null;
|
|
}
|
|
|
|
if (fileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase)) {
|
|
var cleanName = fileName.TrimStart('!', '#');
|
|
|
|
if (doublePaged && fileName.StartsWith('#')) {
|
|
using var reader = new PdfReader(cleanName);
|
|
using var src = new PdfDocument(reader);
|
|
letterheadPage = src.GetPage(1).CopyTo(mergedPdf);
|
|
letterheadInsertIndex = p0;
|
|
letterheadDocIndex = i;
|
|
} else {
|
|
using var reader = new PdfReader(cleanName);
|
|
using var src = new PdfDocument(reader);
|
|
merger.Merge(src, 1, src.GetNumberOfPages());
|
|
}
|
|
} else {
|
|
string tmpFile = tmpFileNames[i];
|
|
if (doublePaged && fileName.StartsWith('#')) {
|
|
using var reader = new PdfReader(tmpFile);
|
|
using var src = new PdfDocument(reader);
|
|
letterheadPage = src.GetPage(1).CopyTo(mergedPdf);
|
|
letterheadInsertIndex = p0;
|
|
letterheadDocIndex = i;
|
|
} else {
|
|
using var reader = new PdfReader(tmpFile);
|
|
using var src = new PdfDocument(reader);
|
|
merger.Merge(src, 1, tmpPageNums[i]);
|
|
}
|
|
}
|
|
|
|
int p1 = mergedPdf.GetNumberOfPages();
|
|
pageNums.Add(p1 - p0);
|
|
|
|
if (doublePaged && fileName[0] != '!' && fileName[0] != '#' && mergedPdf.GetNumberOfPages() % 2 != 0) {
|
|
if (letterheadPage != null) {
|
|
mergedPdf.AddPage(letterheadPage.CopyTo(mergedPdf));
|
|
letterheadPage = null;
|
|
} else {
|
|
mergedPdf.AddNewPage();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (letterheadPage != null) {
|
|
if (mergedPdf.GetNumberOfPages() <= letterheadInsertIndex) {
|
|
mergedPdf.AddPage(letterheadPage.CopyTo(mergedPdf));
|
|
mergedPdf.AddNewPage();
|
|
} else {
|
|
mergedPdf.AddPage(letterheadInsertIndex + 1, letterheadPage.CopyTo(mergedPdf));
|
|
mergedPdf.AddNewPage(letterheadInsertIndex + 2);
|
|
}
|
|
|
|
pageNums[letterheadDocIndex] = 1;
|
|
}
|
|
} finally {
|
|
foreach (var tmp in tmpFileNames) {
|
|
if (File.Exists(tmp)) File.Delete(tmp);
|
|
}
|
|
}
|
|
|
|
return (pageNums.Sum(), pageNums);
|
|
}
|
|
|
|
public static void Show(TempFile file, string title) {
|
|
App.MainDispatcher.BeginInvoke(() => {
|
|
var w = new DocumentViewerWindow(title, file);
|
|
w.Show();
|
|
});
|
|
}
|
|
|
|
public static void Show(string path, string title) {
|
|
App.MainDispatcher.BeginInvoke(() => {
|
|
var w = new DocumentViewerWindow(title, path);
|
|
w.Show();
|
|
});
|
|
}
|
|
|
|
public static async Task Print(string path, int copies = 1, bool doublePaged = false) {
|
|
await Print(path, new() {
|
|
Copies = (short)copies,
|
|
Collate = true,
|
|
Duplex = doublePaged ? Duplex.Vertical : Duplex.Simplex,
|
|
});
|
|
}
|
|
|
|
public static Task Print(string path, PrinterSettings settings) {
|
|
try {
|
|
using var printDoc = new PdfPrintDocument(path) {
|
|
PrinterSettings = settings,
|
|
};
|
|
printDoc.Print();
|
|
} catch (Exception e) {
|
|
MessageBox.Show("Beim Drucken ist ein Fehler aufgetreten:\n\n" + e.Message, "Fehler beim Drucken", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
}
|