From 0f37bfffb7a19b3ec7099eed0480cd1c93c9f04b Mon Sep 17 00:00:00 2001 From: kartik tongaria Date: Sat, 19 Aug 2023 12:59:08 +0530 Subject: [PATCH 1/2] Added img to pdf and docx to pdf file --- src/Plugins/docsx-input-plugin.ts | 34 ++++++++ src/Plugins/image-input-plugin.ts | 23 ++++++ src/Plugins/officegen.d.ts | 4 + src/Plugins/pdf-poppler.d.ts | 4 + src/Plugins/plugin.controller.ts | 126 ++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+) create mode 100644 src/Plugins/docsx-input-plugin.ts create mode 100644 src/Plugins/image-input-plugin.ts create mode 100644 src/Plugins/officegen.d.ts create mode 100644 src/Plugins/pdf-poppler.d.ts create mode 100644 src/Plugins/plugin.controller.ts diff --git a/src/Plugins/docsx-input-plugin.ts b/src/Plugins/docsx-input-plugin.ts new file mode 100644 index 0000000..1175515 --- /dev/null +++ b/src/Plugins/docsx-input-plugin.ts @@ -0,0 +1,34 @@ +import * as path from 'path'; +import * as mammoth from 'mammoth'; +import * as puppeteer from 'puppeteer'; +import { PluginOutput } from './pdf-plugin.interfaces'; + +export class DocxInputPlugin { + public async convertDocxToPdf(docxFilePath: string): Promise { + try { + const outputPdfPath = path.join(__dirname, './generatedPdfDocument.pdf'); + const htmlContent = await this.convertDocxToHtml(docxFilePath); + await this.htmlToPdf(htmlContent, outputPdfPath); + + console.log('PDF file generated successfully'); + return { file: outputPdfPath }; + } catch (error) { + console.error('Error generating PDF:', error); + throw new Error('Failed to convert DOCX to PDF'); + } + } + + private async convertDocxToHtml(docxFilePath: string): Promise { + const result = await mammoth.convertToHtml({ path: docxFilePath }); + return result.value; + } + + private async htmlToPdf(htmlContent: string, pdfPath: string): Promise { + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + await page.setContent(htmlContent); + await page.pdf({ path: pdfPath, format: 'A4' }); + + await browser.close(); + } +} diff --git a/src/Plugins/image-input-plugin.ts b/src/Plugins/image-input-plugin.ts new file mode 100644 index 0000000..b90a37c --- /dev/null +++ b/src/Plugins/image-input-plugin.ts @@ -0,0 +1,23 @@ +import * as fs from 'fs'; +import PDFDocument from 'pdfkit'; + +export class ImageInputPlugin { + async convertImageToPdf( + imageFilePath: string, + pdfFilePath: string, + ): Promise { + const doc = new PDFDocument(); + const output = fs.createWriteStream(pdfFilePath); + + try { + doc.image(imageFilePath, { fit: [600, 800] }); // Adjust dimensions as needed + doc.pipe(output); + doc.end(); + + console.log('Image converted to PDF successfully'); + } catch (error) { + console.error('Error converting image to PDF:', error); + throw new Error('Image to PDF conversion failed'); + } + } +} diff --git a/src/Plugins/officegen.d.ts b/src/Plugins/officegen.d.ts new file mode 100644 index 0000000..4ec4378 --- /dev/null +++ b/src/Plugins/officegen.d.ts @@ -0,0 +1,4 @@ +declare module 'officegen' { + const officegen: any; + export default officegen; // +} diff --git a/src/Plugins/pdf-poppler.d.ts b/src/Plugins/pdf-poppler.d.ts new file mode 100644 index 0000000..8bc32ff --- /dev/null +++ b/src/Plugins/pdf-poppler.d.ts @@ -0,0 +1,4 @@ +declare module 'pdf-poppler' { + export function info(filePath: string): Promise; // + export function convert(filePath: string, options: any): Promise; +} diff --git a/src/Plugins/plugin.controller.ts b/src/Plugins/plugin.controller.ts new file mode 100644 index 0000000..8153394 --- /dev/null +++ b/src/Plugins/plugin.controller.ts @@ -0,0 +1,126 @@ +import { Controller, Post, Get, Param, Dependencies } from '@nestjs/common'; +import * as fs from 'fs'; +import { PluginService } from './pdf-plugin.service'; +import { PluginOutput } from './pdf-plugin.interfaces'; +import { PdfOutputPlugin } from './pdf-output-plugin'; +import { PdfInputPlugin } from './pdf-input-plugin'; +import { DocxOutputPlugin } from './docsx-output-plugin'; +import { DocxInputPlugin } from './docsx-input-plugin'; +import { ImageOutputPlugin } from './image-output-plugin'; // Import the ImageOutputPlugin +import { ImageInputPlugin } from './image-input-plugin'; + +@Controller('plugin') +@Dependencies(PluginService) +export class PluginController { + private pdfOutputPlugin!: PdfOutputPlugin; + private pdfInputPlugin!: PdfInputPlugin; + private docxOutputPlugin!: DocxOutputPlugin; + private docxInputPlugin!: DocxInputPlugin; + private imageOutputPlugin!: ImageOutputPlugin; // Add the ImageOutputPlugin + private imageInputPlugin!: ImageInputPlugin; + constructor(private readonly pluginService: PluginService) {} + + onModuleInit() { + this.pdfOutputPlugin = new PdfOutputPlugin(); + this.pdfInputPlugin = new PdfInputPlugin(); + this.docxOutputPlugin = new DocxOutputPlugin(); + this.docxInputPlugin = new DocxInputPlugin(); + this.imageOutputPlugin = new ImageOutputPlugin(); // Initialize the ImageOutputPlugin + this.imageInputPlugin = new ImageInputPlugin(); + } + + @Post('generate-doc/:outputType') + async generateDocument( + @Param('outputType') outputType: string, + ): Promise { + try { + if (outputType === 'PDF') { + return this.pdfOutputPlugin.generateDoc(outputType); + } else if (outputType === 'DOCX') { + return this.docxOutputPlugin.generateDoc(outputType); + } else if (outputType === 'IMG') { + // Add this condition for image generation + return this.imageOutputPlugin.generateImage(outputType); + } else { + throw new Error('Unsupported output type'); + } + } catch (error: any) { + console.error('Error generating document:', error.message); + throw new Error('Failed to generate document'); + } + } + + @Get('convert-img-to-pdf') + async convertImageToPdf(): Promise { + try { + const imageFilePath = './generatedImage.png'; // Replace with the actual path to the image + const pdfFilePath = './generatedImage.pdf'; + + await this.imageInputPlugin.convertImageToPdf(imageFilePath, pdfFilePath); + + return { file: 'generatedImage.pdf' }; + } catch (error: any) { + console.error('Error converting image to PDF:', error.message); + throw new Error('Failed to convert image to PDF'); + } + } + + @Get('convert-docx-to-pdf') + async convertDocxToPdf(): Promise { + try { + const docxFilePath = './generatedDocxDocument.docx'; // Adjust the path accordingly + const pdfFilePath = './generated-document.pdf'; + + const pluginOutput = await this.docxInputPlugin.convertDocxToPdf( + docxFilePath, + ); + + if (!pluginOutput.file) { + throw new Error('Generated PDF file not found.'); + } + + fs.renameSync(pluginOutput.file, pdfFilePath); + + return { file: 'generated-document.pdf' }; + } catch (error: any) { + console.error('Error converting DOCX to PDF:', error.message); + throw new Error('Failed to convert DOCX to PDF'); + } + } + @Get() + getPluginStatus(): string { + return 'Plugin is running!'; + } + + @Get('/pdf-to-image') + async convertPdfToImage(): Promise<{ images?: { url: string }[] }> { + const pdfFilePath = './generatedDocument.pdf'; + try { + const pluginOutput = await this.pdfInputPlugin.transformPdfToImage( + pdfFilePath, + ); + + if (pluginOutput.images) { + const images = pluginOutput.images; + images.forEach((image: { url: string }) => { + console.log('Image URL:', image.url); + }); + } + + return { images: pluginOutput.images }; + } catch (error) { + console.error('Error converting PDF to image:', error); + throw new Error('PDF to image conversion failed'); + } + } + + @Post('create-default-pdf') + async createDefaultPdf(): Promise { + try { + return this.pdfOutputPlugin.createDefaultPdf(); + } catch (error: any) { + console.error('Error creating default PDF:', error.message); + throw new Error('Failed to create default PDF'); + } + } +} From 51be085dd5a315f8d1cbd52edf018b740baf2211 Mon Sep 17 00:00:00 2001 From: kartik tongaria Date: Sat, 26 Aug 2023 01:25:47 +0530 Subject: [PATCH 2/2] Added Remaing Plugins --- src/Plugins/Drawio-input-plugin.ts | 51 ++++++ src/Plugins/Mermaid.input.plugin.ts | 30 ++++ src/Plugins/excalidraw.input-plugin.ts | 33 ++++ src/Plugins/officegen.d.ts | 2 +- src/Plugins/pdf-poppler.d.ts | 2 +- src/Plugins/plugin.controller.ts | 215 +++++++++++++++++++------ src/Plugins/puppeteer-html-to-pdf.d.ts | 16 ++ 7 files changed, 294 insertions(+), 55 deletions(-) create mode 100644 src/Plugins/Drawio-input-plugin.ts create mode 100644 src/Plugins/Mermaid.input.plugin.ts create mode 100644 src/Plugins/excalidraw.input-plugin.ts create mode 100644 src/Plugins/puppeteer-html-to-pdf.d.ts diff --git a/src/Plugins/Drawio-input-plugin.ts b/src/Plugins/Drawio-input-plugin.ts new file mode 100644 index 0000000..a5c0a12 --- /dev/null +++ b/src/Plugins/Drawio-input-plugin.ts @@ -0,0 +1,51 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { PluginOutput } from './pdf-plugin.interfaces'; +import puppeteer from 'puppeteer'; +import { parseString } from 'xml2js'; + +export class DrawioInputPlugin { + public async convertDrawioFileToPdf( + drawioFilePath: string, + ): Promise { + try { + // Read Draw.io file content + const drawioXml = fs.readFileSync(drawioFilePath, 'utf-8'); + + // Parse Draw.io XML to JavaScript object + let drawioJson; + parseString(drawioXml, (err, result) => { + if (err) { + throw err; + } + drawioJson = result; + }); + + // Convert Draw.io JSON object to HTML (manually or using a templating engine) + const drawioHtml = `
${JSON.stringify(drawioJson)}
`; + + // Launch a headless browser instance + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + + // Set the content of the page to the Draw.io HTML + await page.setContent(drawioHtml); + + // Generate a PDF from the rendered HTML content + const pdfBuffer = await page.pdf(); + + // Close the browser + await browser.close(); + + const pdfFilePath = path.join(__dirname, 'generatedDrawio.pdf'); // Adjust the path accordingly + fs.writeFileSync(pdfFilePath, pdfBuffer); + + console.log('Draw.io PDF generated successfully'); + + return { file: 'generatedDrawio.pdf' }; + } catch (error) { + console.error('Error converting Draw.io file to PDF:', error); + throw new Error('Failed to convert Draw.io file to PDF'); + } + } +} diff --git a/src/Plugins/Mermaid.input.plugin.ts b/src/Plugins/Mermaid.input.plugin.ts new file mode 100644 index 0000000..78bb703 --- /dev/null +++ b/src/Plugins/Mermaid.input.plugin.ts @@ -0,0 +1,30 @@ +import { PluginOutput } from './pdf-plugin.interfaces'; // Make sure you import the correct interface +import puppeteer from 'puppeteer'; + +export class MermaidInputPlugin { + public async convertMermaidToPdf(mermaidContent: any): Promise { + try { + const pdfFilePath = `./generatedMermaid.pdf`; // Adjust the path + + // Launch a headless browser + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + + // Set the content of the page to the Mermaid diagram HTML + const htmlContent = `
${mermaidContent}
`; + await page.setContent(htmlContent); + + // Generate a PDF from the Mermaid diagram HTML + await page.pdf({ path: pdfFilePath, format: 'A4' }); + + await browser.close(); + + console.log('Mermaid PDF generated successfully'); + + return { file: 'generatedMermaid.pdf' }; + } catch (error) { + console.error('Error generating Mermaid PDF:', error); + throw new Error('Failed to convert Mermaid to PDF'); + } + } +} diff --git a/src/Plugins/excalidraw.input-plugin.ts b/src/Plugins/excalidraw.input-plugin.ts new file mode 100644 index 0000000..4a97cc0 --- /dev/null +++ b/src/Plugins/excalidraw.input-plugin.ts @@ -0,0 +1,33 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { PluginOutput } from './pdf-plugin.interfaces'; // Make sure you import the correct interface +import puppeteer from 'puppeteer'; + +export class ExcalidrawInputPlugin { + public async convertExcalidrawToPdf( + excalidrawContent: string, + ): Promise { + try { + const pdfFilePath = path.join(__dirname, 'generatedExcalidraw.pdf'); // Adjust the path + + // Launch a headless browser + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + + // Set the content of the page to the Excalidraw SVG + await page.setContent(excalidrawContent); + + // Generate a PDF from the SVG + await page.pdf({ path: pdfFilePath, format: 'A4' }); + + await browser.close(); + + console.log('Excalidraw PDF generated successfully'); + + return { file: pdfFilePath }; + } catch (error) { + console.error('Error generating Excalidraw PDF:', error); + throw new Error('Failed to convert Excalidraw to PDF'); + } + } +} diff --git a/src/Plugins/officegen.d.ts b/src/Plugins/officegen.d.ts index 4ec4378..a6f8d2d 100644 --- a/src/Plugins/officegen.d.ts +++ b/src/Plugins/officegen.d.ts @@ -1,4 +1,4 @@ declare module 'officegen' { const officegen: any; - export default officegen; // + export default officegen; } diff --git a/src/Plugins/pdf-poppler.d.ts b/src/Plugins/pdf-poppler.d.ts index 8bc32ff..7872b86 100644 --- a/src/Plugins/pdf-poppler.d.ts +++ b/src/Plugins/pdf-poppler.d.ts @@ -1,4 +1,4 @@ declare module 'pdf-poppler' { export function info(filePath: string): Promise; // export function convert(filePath: string, options: any): Promise; -} +} // diff --git a/src/Plugins/plugin.controller.ts b/src/Plugins/plugin.controller.ts index 8153394..d25aa36 100644 --- a/src/Plugins/plugin.controller.ts +++ b/src/Plugins/plugin.controller.ts @@ -1,4 +1,14 @@ -import { Controller, Post, Get, Param, Dependencies } from '@nestjs/common'; +import { + Controller, + Post, + Query, + UseInterceptors, + Res, + Get, + Body, + Param, + Dependencies, +} from '@nestjs/common'; import * as fs from 'fs'; import { PluginService } from './pdf-plugin.service'; import { PluginOutput } from './pdf-plugin.interfaces'; @@ -8,6 +18,12 @@ import { DocxOutputPlugin } from './docsx-output-plugin'; import { DocxInputPlugin } from './docsx-input-plugin'; import { ImageOutputPlugin } from './image-output-plugin'; // Import the ImageOutputPlugin import { ImageInputPlugin } from './image-input-plugin'; +import { DrawioInputPlugin } from './Drawio-input-plugin'; +import * as path from 'path'; +import { parseString } from 'xml2js'; // Import parseString from xml2js +import puppeteer from 'puppeteer'; +import { ExcalidrawInputPlugin } from './excalidraw.input-plugin'; // Adjust the import path +import { MermaidInputPlugin } from './Mermaid.input.plugin'; // Adjust the import path @Controller('plugin') @Dependencies(PluginService) @@ -18,6 +34,9 @@ export class PluginController { private docxInputPlugin!: DocxInputPlugin; private imageOutputPlugin!: ImageOutputPlugin; // Add the ImageOutputPlugin private imageInputPlugin!: ImageInputPlugin; + private ExcalidrawInputPlugin!: ExcalidrawInputPlugin; + private MermaidInputPlugin!: MermaidInputPlugin; + private DrawioInputPlugin!: DrawioInputPlugin; constructor(private readonly pluginService: PluginService) {} onModuleInit() { @@ -27,38 +46,71 @@ export class PluginController { this.docxInputPlugin = new DocxInputPlugin(); this.imageOutputPlugin = new ImageOutputPlugin(); // Initialize the ImageOutputPlugin this.imageInputPlugin = new ImageInputPlugin(); + this.ExcalidrawInputPlugin = new ExcalidrawInputPlugin(); + this.DrawioInputPlugin = new DrawioInputPlugin(); + this.MermaidInputPlugin = new MermaidInputPlugin(); } - @Post('generate-doc/:outputType') - async generateDocument( - @Param('outputType') outputType: string, - ): Promise { + @Get() + getPluginStatus(): string { + return 'Plugin is running!'; + } + + @Post('generate-pdf') + async generatePdf(@Body() userInput: string[]): Promise { try { - if (outputType === 'PDF') { - return this.pdfOutputPlugin.generateDoc(outputType); - } else if (outputType === 'DOCX') { - return this.docxOutputPlugin.generateDoc(outputType); - } else if (outputType === 'IMG') { - // Add this condition for image generation - return this.imageOutputPlugin.generateImage(outputType); - } else { - throw new Error('Unsupported output type'); - } + const result = await this.pdfOutputPlugin.generateDoc('pdf', userInput); + return result; + } catch (error: any) { + console.error('Error generating PDF:', error.message); + throw new Error('Failed to generate PDF'); + } + } + + @Post('create-default-pdf') + async createDefaultPdf(): Promise { + try { + return this.pdfOutputPlugin.createDefaultPdf(); + } catch (error: any) { + console.error('Error creating default PDF:', error.message); + throw new Error('Failed to create default PDF'); + } + } + @Post('generate-docx') + async generateDocx(@Body() userInput: string[]): Promise { + try { + const result = await this.docxOutputPlugin.generateDoc('docx', userInput); + return result; } catch (error: any) { - console.error('Error generating document:', error.message); - throw new Error('Failed to generate document'); + console.error('Error generating DOCX:', error.message); + throw new Error('Failed to generate DOCX'); + } + } + @Post('generate-image') + async generateImage(@Body() userInput: string): Promise { + try { + return await this.imageOutputPlugin.generateImage('img', userInput); + } catch (error: any) { + console.error('Error generating image:', error.message); + throw new Error('Failed to generate image'); } } - @Get('convert-img-to-pdf') - async convertImageToPdf(): Promise { + @Get('convert-image-to-pdf') + async convertImageToPdf( + @Query('imagePath') imagePath: string, + ): Promise { try { - const imageFilePath = './generatedImage.png'; // Replace with the actual path to the image - const pdfFilePath = './generatedImage.pdf'; + if (!imagePath) { + console.error('Image file path not provided.'); + throw new Error('Image file path not provided.'); + } - await this.imageInputPlugin.convertImageToPdf(imageFilePath, pdfFilePath); + const pdfFilePath = `./generatedImage.pdf`; // Output PDF file path - return { file: 'generatedImage.pdf' }; + await this.imageInputPlugin.convertImageToPdf(imagePath, pdfFilePath); + + return { pdfPath: pdfFilePath }; } catch (error: any) { console.error('Error converting image to PDF:', error.message); throw new Error('Failed to convert image to PDF'); @@ -66,61 +118,118 @@ export class PluginController { } @Get('convert-docx-to-pdf') - async convertDocxToPdf(): Promise { + async convertDocxToPdf( + @Query('docxPath') docxPath: string, + ): Promise { try { - const docxFilePath = './generatedDocxDocument.docx'; // Adjust the path accordingly - const pdfFilePath = './generated-document.pdf'; + if (!docxPath) { + console.error('DOCX file path not provided.'); + throw new Error('DOCX file path not provided.'); + } const pluginOutput = await this.docxInputPlugin.convertDocxToPdf( - docxFilePath, + docxPath, ); if (!pluginOutput.file) { throw new Error('Generated PDF file not found.'); } - fs.renameSync(pluginOutput.file, pdfFilePath); - - return { file: 'generated-document.pdf' }; + return { file: 'generatedPdfDocument.pdf' }; } catch (error: any) { console.error('Error converting DOCX to PDF:', error.message); throw new Error('Failed to convert DOCX to PDF'); } } - @Get() - getPluginStatus(): string { - return 'Plugin is running!'; - } - @Get('/pdf-to-image') - async convertPdfToImage(): Promise<{ images?: { url: string }[] }> { - const pdfFilePath = './generatedDocument.pdf'; + @Get('convert-docx-to-images') + async convertDocxToImages( + @Query('docxPath') docxPath: string, + ): Promise { try { - const pluginOutput = await this.pdfInputPlugin.transformPdfToImage( - pdfFilePath, + if (!docxPath) { + console.error('DOCX file path not provided.'); + throw new Error('DOCX file path not provided.'); + } + + const pluginOutput = await this.docxInputPlugin.convertDocxToImages( + docxPath, ); - if (pluginOutput.images) { - const images = pluginOutput.images; - images.forEach((image: { url: string }) => { - console.log('Image URL:', image.url); - }); + if (!pluginOutput.folder) { + throw new Error('Generated images folder not found.'); } - return { images: pluginOutput.images }; - } catch (error) { - console.error('Error converting PDF to image:', error); - throw new Error('PDF to image conversion failed'); + return { folder: pluginOutput.folder }; + } catch (error: any) { + console.error('Error converting DOCX to images:', error.message); + throw new Error('Failed to convert DOCX to images'); } } - @Post('create-default-pdf') - async createDefaultPdf(): Promise { + @Get('convert-drawio-to-pdf') + async convertDrawioFileToPdf(): Promise { try { - return this.pdfOutputPlugin.createDefaultPdf(); + const drawioFilePath = + 'C:/Users/Kartik/Documents/C4gt/Doc-Generator/abc.drawio'; // Adjust the path accordingly + const pluginOutput = await this.DrawioInputPlugin.convertDrawioFileToPdf( + drawioFilePath, + ); + + return pluginOutput; } catch (error: any) { - console.error('Error creating default PDF:', error.message); - throw new Error('Failed to create default PDF'); + console.error('Error converting Draw.io file to PDF:', error.message); + throw new Error('Failed to convert Draw.io file to PDF'); + } + } + + @Get('convert-excalidraw-to-pdf') + async convertExcalidrawToPdf( + @Query('excalidrawpath') excalidrawContent: string, + ): Promise { + try { + if (!excalidrawContent) { + console.error('Excalidraw content not provided.'); + throw new Error('Excalidraw content not provided.'); + } + + const pluginOutput = + await this.ExcalidrawInputPlugin.convertExcalidrawToPdf( + excalidrawContent, + ); + + if (!pluginOutput.file) { + throw new Error('Generated PDF file not found.'); + } + + return { file: pluginOutput.file }; // Use the correct property from the pluginOutput + } catch (error: any) { + console.error('Error converting Excalidraw to PDF:', error.message); + throw new Error('Failed to convert Excalidraw to PDF'); + } + } + @Get('convert-drawio-to-pdf') + async convertDrawioToPdf( + @Query('drawioFilePath') drawioFilePath: string, + ): Promise { + try { + if (!drawioFilePath) { + console.error('Draw.io file path not provided.'); + throw new Error('Draw.io file path not provided.'); + } + + const pluginOutput = await this.DrawioInputPlugin.convertDrawioFileToPdf( + drawioFilePath, + ); + + if (!pluginOutput.file) { + throw new Error('Generated PDF file not found.'); + } + + return { file: pluginOutput.file }; + } catch (error: any) { + console.error('Error converting Draw.io to PDF:', error.message); + throw new Error('Failed to convert Draw.io to PDF'); } } } diff --git a/src/Plugins/puppeteer-html-to-pdf.d.ts b/src/Plugins/puppeteer-html-to-pdf.d.ts new file mode 100644 index 0000000..f530b8a --- /dev/null +++ b/src/Plugins/puppeteer-html-to-pdf.d.ts @@ -0,0 +1,16 @@ +declare module 'puppeteer-html-to-pdf' { + interface Page { + goto: (url: string) => Promise; + waitForSelector: (selector: string) => Promise; + evaluate: (fn: (xml: string) => void, xml: string) => Promise; + } + + interface Browser { + newPage: () => Promise; + close: () => Promise; + } + + function initBrowser(): Promise; + + function generatePdfBuffer(page: Page): Promise; +}