Skip to content

Commit 852ac2c

Browse files
authored
Merge pull request #8 from OsamaRab3/merge
Add: Merge command to merge multiples file
1 parent c4f37ea commit 852ac2c

File tree

5 files changed

+150
-1
lines changed

5 files changed

+150
-1
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@
3636
- **PDF** → Images (JPG)
3737
- **PDF** → Text (TXT) - Extract text content from PDF files
3838
- **PDF Info** → Display metadata (title, creator, page count, file size)
39+
- Merge multiple PDFs
3940

4041
#### Coming Soon
4142
- PowerPoint → PDF
4243
- Excel → PDF
4344
- HTML → PDF
44-
- Merge multiple PDFs
4545
- PDF compression
4646
- PDF text extraction
4747

@@ -158,6 +158,22 @@ filto extract input.pdf -o extracted.txt
158158
```
159159
filto extract input.pdf --page 1 --output page1.txt
160160
```
161+
---
162+
### 5. Merge PDF Files
163+
Merge multiple PDF files into a single PDF
164+
165+
**Basic usage:**
166+
```
167+
filto merge file1.pdf file2.pdf output.pdf
168+
```
169+
170+
**Example with multiple files:**
171+
```
172+
filto merge doc1.pdf doc2.pdf doc3.pdf merged_output.pdf
173+
```
174+
175+
> **Note:** You need to provide at least two PDF files to merge. The last argument will be used as the output file.
176+
161177
---
162178
## Contributing
163179

package-lock.json

Lines changed: 55 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@oclif/plugin-plugins": "^5",
1818
"asposepdfnodejs": "^25.10.0",
1919
"image-to-pdf": "^3.0.2",
20+
"pdf-lib": "^1.17.1",
2021
"pdf-parse": "^2.4.5",
2122
"rewiremock": "^3.14.6"
2223
},

src/commands/merge/index.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Args, Command, Flags } from '@oclif/core'
2+
import { MergePdfs } from '../../merge/index.js';
3+
export default class Merge extends Command {
4+
static override description = ' Merge multiple PDFs'
5+
6+
static override args = {
7+
inputs: Args.string({ description: 'Input PDF files to merge', required: true, multiple: true }),
8+
output: Args.string({ description: 'Output merged PDF file', required: true }),
9+
}
10+
static override strict = false;
11+
12+
public async run(): Promise<void> {
13+
const { args } = await this.parse(Merge)
14+
const { inputs } = args;
15+
16+
if (inputs.length < 2) {
17+
this.error('Please provide at least two PDF files to merge.');
18+
}
19+
20+
try {
21+
const argv = process.argv;
22+
const inputsArr = argv.slice(3, argv.length - 1);
23+
const result = await MergePdfs(inputsArr, argv[argv.length - 1]);
24+
25+
if (result.success) {
26+
this.log(result.message);
27+
} else {
28+
this.error(result.message);
29+
}
30+
} catch (error: any) {
31+
this.error(`Unexpected error during merge: ${error.message}`);
32+
}
33+
34+
}
35+
}

src/merge/index.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
import { PDFDocument } from 'pdf-lib';
3+
import fs from 'fs';
4+
import ConversionResult from '../types/converstionResult.js';
5+
6+
export async function MergePdfs(inputPdf: string[], output: string = "merged.pdf"): Promise<ConversionResult> {
7+
if (!fs.existsSync(inputPdf[0])) {
8+
return {
9+
success: false,
10+
message: `Input file not found: ${inputPdf}`
11+
};
12+
}
13+
14+
try {
15+
const pdfToMerge = inputPdf.map(filePath => fs.readFileSync(filePath));
16+
17+
const mergedPdf = await PDFDocument.create();
18+
for (const pdfBytes of pdfToMerge) {
19+
const pdf = await PDFDocument.load(pdfBytes);
20+
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
21+
copiedPages.forEach((page) => {
22+
mergedPdf.addPage(page);
23+
});
24+
}
25+
26+
const buf = await mergedPdf.save();
27+
fs.writeFileSync(output, buf);
28+
29+
return {
30+
success: true,
31+
message: `Successfully Merged PDFs: ${inputPdf.map(pdf => {
32+
return pdf
33+
})} into -> ${output}`
34+
};
35+
} catch (error: any) {
36+
return {
37+
success: false,
38+
message: `Error during Merge: ${error.message}`,
39+
error
40+
};
41+
}
42+
}

0 commit comments

Comments
 (0)