Compare commits
3 Commits
9adc9ac4ed
...
a087baa089
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a087baa089 | ||
|
|
98226f239b | ||
|
|
1144c45826 |
@@ -38,7 +38,7 @@ public class PdfAttachmentExtractorService(
|
||||
};
|
||||
result.PdfAWarning = compatibility == PdfACompatibility.None;
|
||||
|
||||
logger.LogInformation(
|
||||
logger.LogDebug(
|
||||
"PDF '{FileName}': Konformität = {Level}",
|
||||
sourceFileName, result.PdfALevel);
|
||||
|
||||
@@ -50,7 +50,7 @@ public class PdfAttachmentExtractorService(
|
||||
{
|
||||
result.ZugferdGuidelineId = ExtractGuidelineId(xmpData);
|
||||
if (!string.IsNullOrEmpty(result.ZugferdGuidelineId))
|
||||
logger.LogInformation(
|
||||
logger.LogDebug(
|
||||
"PDF '{FileName}': Guideline-ID = {GuidelineId}",
|
||||
sourceFileName, result.ZugferdGuidelineId);
|
||||
}
|
||||
@@ -105,7 +105,7 @@ public class PdfAttachmentExtractorService(
|
||||
|
||||
var isZugferd = IsZugferdXml(attachment.FileName);
|
||||
|
||||
logger.LogInformation(
|
||||
logger.LogDebug(
|
||||
" → Gespeichert: '{FileName}' ({Bytes} Bytes){Zugferd}",
|
||||
safeFileName, data.Length,
|
||||
isZugferd ? " [ZUGFeRD/Factur-X XML]" : string.Empty);
|
||||
|
||||
@@ -21,7 +21,7 @@ public class PdfResultPackageService(
|
||||
return null;
|
||||
}
|
||||
|
||||
logger.LogInformation(
|
||||
logger.LogDebug(
|
||||
"Ergebnisbericht gefunden: '{ReportPath}'.", reportPath);
|
||||
|
||||
// 2. Ausgabepfad bestimmen
|
||||
@@ -35,20 +35,28 @@ public class PdfResultPackageService(
|
||||
// 3. Original auf PDF/A-3b hochstufen + Bericht anhängen
|
||||
await Task.Run(() =>
|
||||
{
|
||||
// Original in MemoryStream laden
|
||||
using var inputStream = new MemoryStream(originalPdfBytes);
|
||||
using var outputStream = new MemoryStream();
|
||||
|
||||
// PDF/A-3b Konvertierung
|
||||
var converter = new PdfDocumentConverter(inputStream);
|
||||
// Schritt 1: PDF/A-3b Konvertierung
|
||||
PdfDocumentConverter converter;
|
||||
try
|
||||
{
|
||||
converter = new PdfDocumentConverter(inputStream);
|
||||
converter.Convert(PdfCompatibility.PdfA3b);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Konvertierung nach PDF/A-3b fehlgeschlagen. " +
|
||||
"Die Originaldatei ist möglicherweise beschädigt oder nicht konvertierbar.", ex);
|
||||
}
|
||||
|
||||
// Konvertiertes PDF in MemoryStream speichern
|
||||
// Schritt 2: Konvertiertes PDF puffern
|
||||
using var convertedStream = new MemoryStream();
|
||||
converter.SaveDocument(convertedStream);
|
||||
convertedStream.Position = 0;
|
||||
|
||||
// Bericht als Anhang einbetten
|
||||
// Schritt 3: Anhang einbetten
|
||||
using var processor = new PdfDocumentProcessor();
|
||||
processor.LoadDocument(convertedStream);
|
||||
|
||||
@@ -62,8 +70,65 @@ public class PdfResultPackageService(
|
||||
Data = File.ReadAllBytes(reportPath)
|
||||
});
|
||||
|
||||
// Speichern
|
||||
// Schritt 4: Stempel auf Seite 1 zeichnen
|
||||
var firstPage = processor.Document.Pages[0];
|
||||
using (var graphics = processor.CreateGraphicsWorldSystem())
|
||||
{
|
||||
// Stempel-Position: oben rechts
|
||||
// Welt-Koordinaten: Ursprung oben links, X nach rechts, Y nach unten
|
||||
var stampX = (float)firstPage.CropBox.Width - 200;
|
||||
var stampY = 20f;
|
||||
var stampWidth = 175f;
|
||||
var stampHeight = 50f;
|
||||
|
||||
// Hintergrund weiß
|
||||
using var whiteBrush = new DevExpress.Drawing.DXSolidBrush(
|
||||
System.Drawing.Color.White);
|
||||
graphics.FillRectangle(whiteBrush,
|
||||
new System.Drawing.RectangleF(stampX, stampY, stampWidth, stampHeight));
|
||||
|
||||
// Rahmen grün
|
||||
using var greenPen = new DevExpress.Drawing.DXPen(
|
||||
System.Drawing.Color.Green, 1.5f);
|
||||
graphics.DrawRectangle(greenPen,
|
||||
new System.Drawing.RectangleF(stampX, stampY, stampWidth, stampHeight));
|
||||
|
||||
// Text Zeile 1: VERARBEITET
|
||||
using var greenBrush = new DevExpress.Drawing.DXSolidBrush(
|
||||
System.Drawing.Color.Green);
|
||||
var fontBold = new DevExpress.Drawing.DXFont(
|
||||
"Arial", 11, DevExpress.Drawing.DXFontStyle.Bold);
|
||||
graphics.DrawString(
|
||||
"✔ VERARBEITET",
|
||||
fontBold,
|
||||
greenBrush,
|
||||
new System.Drawing.PointF(stampX + 8, stampY + 6));
|
||||
|
||||
// Text Zeile 2: Datum/Uhrzeit
|
||||
using var grayBrush = new DevExpress.Drawing.DXSolidBrush(
|
||||
System.Drawing.Color.DimGray);
|
||||
var fontNormal = new DevExpress.Drawing.DXFont("Arial", 9);
|
||||
graphics.DrawString(
|
||||
DateTime.Now.ToString("dd.MM.yyyy HH:mm"),
|
||||
fontNormal,
|
||||
grayBrush,
|
||||
new System.Drawing.PointF(stampX + 8, stampY + 28));
|
||||
|
||||
graphics.AddToPageForeground(
|
||||
processor.Document.Pages[0], 96, 96);
|
||||
}
|
||||
|
||||
// Schritt 4: Speichern
|
||||
try
|
||||
{
|
||||
processor.SaveDocument(outputPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Result-PDF konnte nicht gespeichert werden unter '{outputPath}'. " +
|
||||
"Prüfe ob das Verzeichnis existiert und beschreibbar ist.", ex);
|
||||
}
|
||||
});
|
||||
|
||||
logger.LogInformation(
|
||||
|
||||
Reference in New Issue
Block a user