From b47ad175689c41a5c6762bce8195374a7483b942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20P=C3=B6ttker?= Date: Tue, 5 May 2026 08:06:52 +0200 Subject: [PATCH] feat: support selective page range extraction for email attachment print previews --- .../src/email/email-import.service.ts | 19 ++++++++++++++++++- paperless-frontend/src/api/email-import.ts | 4 ++-- .../src/components/MailImportWizard.tsx | 7 +++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/paperless-backend/src/email/email-import.service.ts b/paperless-backend/src/email/email-import.service.ts index 9758953..c7f7450 100644 --- a/paperless-backend/src/email/email-import.service.ts +++ b/paperless-backend/src/email/email-import.service.ts @@ -158,7 +158,24 @@ export class EmailImportService { async generatePrintPdf(attachmentId: number, barcodeData: any): Promise { const content = await this.contentRepo.findOne({ where: { AttachmentEntityId: attachmentId } }); if (!content) throw new HttpException('Inhalt nicht gefunden', HttpStatus.NOT_FOUND); - return this.applyBarcodeToPdf(content.Content1, barcodeData); + + let pdfBytes: Buffer = content.Content1; + + const pages: { start: number; end: number } | undefined = barcodeData._pages; + if (pages) { + const pdfDoc = await PDFDocument.load(pdfBytes, { ignoreEncryption: true }); + const total = pdfDoc.getPageCount(); + const startIdx = Math.max(1, pages.start) - 1; + const endIdx = Math.min(pages.end === 999 ? total : pages.end, total) - 1; + const sliced = await PDFDocument.create(); + const indices = Array.from({ length: endIdx - startIdx + 1 }, (_, i) => startIdx + i); + const copied = await sliced.copyPages(pdfDoc, indices); + copied.forEach(p => sliced.addPage(p)); + pdfBytes = Buffer.from(await sliced.save()); + } + + const { _pages, ...barcode } = barcodeData; + return this.applyBarcodeToPdf(pdfBytes, barcode); } async applyBarcodeToPdf(pdfBytes: Buffer, barcodeData: any): Promise { diff --git a/paperless-frontend/src/api/email-import.ts b/paperless-frontend/src/api/email-import.ts index dc8ef9e..e6cc51f 100644 --- a/paperless-frontend/src/api/email-import.ts +++ b/paperless-frontend/src/api/email-import.ts @@ -50,8 +50,8 @@ export const emailImportApi = { await api.post('/api/email-import/belegnummer/release', { date: dateStr, number }); }, - printPreview: async (attachmentId: number, barcodeData: any): Promise => { - const res = await api.post(`/api/email-import/attachments/${attachmentId}/print-preview`, barcodeData, { + printPreview: async (attachmentId: number, barcodeData: any, pages?: { start: number; end: number }): Promise => { + const res = await api.post(`/api/email-import/attachments/${attachmentId}/print-preview`, { ...barcodeData, _pages: pages }, { responseType: 'blob', }); return res.data; diff --git a/paperless-frontend/src/components/MailImportWizard.tsx b/paperless-frontend/src/components/MailImportWizard.tsx index 1e57500..075987d 100644 --- a/paperless-frontend/src/components/MailImportWizard.tsx +++ b/paperless-frontend/src/components/MailImportWizard.tsx @@ -365,8 +365,11 @@ export default function MailImportWizard({ visible, onClose, email, attachments printWindow.close(); return; } - - const blob = await emailImportApi.printPreview(attachmentId, barcode); + + const item = importData.find(i => i.virtualId === virtualId); + const pages = item?.pages; + + const blob = await emailImportApi.printPreview(attachmentId, barcode, pages); const url = window.URL.createObjectURL(blob); // Navigate the already open window to the PDF