feat(pdf-tools): add attachments feature to embed files in PDFs

Implement new functionality to allow embedding attachments into PDF documents. The feature includes:
- UI for selecting PDF and files to attach
- Logic to embed files while preserving metadata
- Display of attached files with size information
- Download of modified PDF with embedded files
This commit is contained in:
abdullahalam123
2025-10-19 15:02:27 +05:30
parent ddeebc8142
commit 88e05e6713
11 changed files with 222 additions and 33 deletions

View File

@@ -30,7 +30,9 @@ async function initializeQpdf() {
export async function linearizePdf() {
// Check if there are files and at least one PDF
const pdfFiles = state.files.filter((file: File) => file.type === 'application/pdf');
const pdfFiles = state.files.filter(
(file: File) => file.type === 'application/pdf'
);
if (!pdfFiles || pdfFiles.length === 0) {
showAlert('No PDF Files', 'Please upload at least one PDF file.');
return;
@@ -43,12 +45,12 @@ export async function linearizePdf() {
let errorCount = 0;
try {
qpdf = await initializeQpdf();
qpdf = await initializeQpdf();
for (let i = 0; i < pdfFiles.length; i++) {
const file = pdfFiles[i];
const inputPath = `/input_${i}.pdf`;
const outputPath = `/output_${i}.pdf`;
const inputPath = `/input_${i}.pdf`;
const outputPath = `/output_${i}.pdf`;
showLoader(`Optimizing ${file.name} (${i + 1}/${pdfFiles.length})...`);
@@ -58,23 +60,20 @@ export async function linearizePdf() {
qpdf.FS.writeFile(inputPath, uint8Array);
const args = [
inputPath,
'--linearize',
outputPath,
];
const args = [inputPath, '--linearize', outputPath];
qpdf.callMain(args);
const outputFile = qpdf.FS.readFile(outputPath, { encoding: 'binary' });
if (!outputFile || outputFile.length === 0) {
console.error(`Linearization resulted in an empty file for ${file.name}.`);
throw new Error(`Processing failed for ${file.name}.`);
}
if (!outputFile || outputFile.length === 0) {
console.error(
`Linearization resulted in an empty file for ${file.name}.`
);
throw new Error(`Processing failed for ${file.name}.`);
}
zip.file(`linearized-${file.name}`, outputFile, { binary: true });
successCount++;
} catch (fileError: any) {
errorCount++;
console.error(`Failed to linearize ${file.name}:`, fileError);
@@ -91,13 +90,16 @@ export async function linearizePdf() {
}
}
} catch (cleanupError) {
console.warn(`Failed to cleanup WASM FS for ${file.name}:`, cleanupError);
console.warn(
`Failed to cleanup WASM FS for ${file.name}:`,
cleanupError
);
}
}
}
}
if (successCount === 0) {
throw new Error('No PDF files could be linearized.');
throw new Error('No PDF files could be linearized.');
}
showLoader('Generating ZIP file...');
@@ -109,7 +111,6 @@ export async function linearizePdf() {
alertMessage += ` ${errorCount} file(s) failed.`;
}
showAlert('Processing Complete', alertMessage);
} catch (error: any) {
console.error('Linearization process error:', error);
showAlert(
@@ -119,4 +120,4 @@ export async function linearizePdf() {
} finally {
hideLoader();
}
}
}