0% found this document useful (0 votes)
5 views4 pages

PDF Resume Generator with Templates

The document outlines a Node.js application using Express and Puppeteer to generate PDF resumes based on user input. It includes a POST endpoint '/generate-pdf' that accepts resume data, dynamically creates HTML content based on selected templates, and returns a generated PDF. Additionally, it features a React component for editing content and a function to handle PDF generation requests from the client side.

Uploaded by

Nilanjana Das
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views4 pages

PDF Resume Generator with Templates

The document outlines a Node.js application using Express and Puppeteer to generate PDF resumes based on user input. It includes a POST endpoint '/generate-pdf' that accepts resume data, dynamically creates HTML content based on selected templates, and returns a generated PDF. Additionally, it features a React component for editing content and a function to handle PDF generation requests from the client side.

Uploaded by

Nilanjana Das
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

const express = require('express');

const puppeteer = require('puppeteer');

const app = express();


const PORT = 5000;

[Link]([Link]());

[Link]('/generate-pdf', async (req, res) => {


const { basicInfoData, eduData, expData, summaryText, skills } = [Link];

const html = `
<html>
<head>
<style>
body { font-family: Arial, sans-serif; padding: 40px; }
h1 { color: #222; }
.section { margin-bottom: 20px; }
</style>
</head>
<body>
<h1>${[Link]}</h1>

<div class="section">
<h2>Education</h2>
${[Link](edu => `<p>${[Link]} at
${[Link]}</p>`).join('')}
</div>

<div class="section">
<h2>Experience</h2>
${[Link](exp => `<p>${[Link]} at
${[Link]}</p>`).join('')}
</div>

<div class="section">
<h2>Skills</h2>
<p>${[Link](', ')}</p>
</div>

<div class="section">
<h2>Summary</h2>
<p>${summaryText}</p>
</div>
</body>
</html>
`;

try {
const browser = await [Link]();
const page = await [Link]();
await [Link](html, { waitUntil: 'networkidle0' });

const pdf = await [Link]({ format: 'A4' });


await [Link]();

[Link]({
'Content-Type': 'application/pdf',
'Content-Disposition': 'inline; filename="[Link]"',
});

[Link](pdf);
} catch (error) {
[Link]('PDF generation error:', error);
[Link](500).send('Failed to generate PDF');
}
});

[Link](PORT, () => {
[Link](`PDF generator running at [Link]
});

<ReactQuill
className="custom-editor"
modules={modules}
formats={formats}
placeholder="Write your additional details...."
onChange={handleContentChange}
value={customField}
/>

<style jsx global>{`


.custom-editor .ql-container {
border: none;
background-color: rgb(239, 242, 249);
min-height: 2220px;
}

.custom-editor .ql-editor {
background-color: rgb(239, 242, 249);
min-height: 2220px;
}
`}</style>

[Link]('/generate-pdf', async (req, res) => {


const { basicInfoData, eduData, expData, summaryText, skills, selectedTemplate }
= [Link];

// Dynamically generate HTML based on selected template


let htmlTemplate = '';

if (selectedTemplate === 'template1') {


htmlTemplate = `
<html>
<head>
<style>
body { font-family: Arial, sans-serif; padding: 40px; }
h1 { color: #222; }
.section { margin-bottom: 20px; }
</style>
</head>
<body>
<h1>${[Link]}</h1>
<div class="section">
<h2>Education</h2>
${[Link](edu => `<p>${[Link]} at
${[Link]}</p>`).join('')}
</div>
<div class="section">
<h2>Experience</h2>
${[Link](exp => `<p>${[Link]} at
${[Link]}</p>`).join('')}
</div>
<div class="section">
<h2>Skills</h2>
<p>${[Link](', ')}</p>
</div>
<div class="section">
<h2>Summary</h2>
<p>${summaryText}</p>
</div>
</body>
</html>
`;
} else if (selectedTemplate === 'template2') {
htmlTemplate = `
<html>
<head>
<style>
body { font-family: 'Times New Roman', serif; padding: 30px; }
h1 { text-align: center; color: #333; }
.section { margin-bottom: 30px; }
</style>
</head>
<body>
<h1>${[Link]}</h1>
<div class="section">
<h2>Education</h2>
${[Link](edu => `<p><strong>${[Link]}</strong> at <em>$
{[Link]}</em></p>`).join('')}
</div>
<div class="section">
<h2>Experience</h2>
${[Link](exp => `<p><strong>${[Link]}</strong> at <i>$
{[Link]}</i></p>`).join('')}
</div>
<div class="section">
<h2>Skills</h2>
<ul>${[Link](skill => `<li>${skill}</li>`).join('')}</ul>
</div>
<div class="section">
<h2>Summary</h2>
<p>${summaryText}</p>
</div>
</body>
</html>
`;
}

try {
const browser = await [Link]();
const page = await [Link]();
await [Link](htmlTemplate, { waitUntil: 'networkidle0' });

const pdf = await [Link]({


scale: 1,
displayHeaderFooter: true,
printBackground: true,
margin: {
top: 10,
right: 10,
bottom: 10,
left: 10,
},
format: 'A4',
});
await [Link]();

[Link]({
'Content-Type': 'application/pdf',
'Content-Disposition': 'inline; filename="[Link]"',
});

[Link](pdf);
} catch (error) {
[Link]('PDF generation error:', error);
[Link](500).send('Failed to generate PDF');
}
});

const handleGeneratePDF = async () => {


const resumeData = {
basicInfoData: { fullName: "John Doe", email: "john@[Link]" },
eduData: [{ degree: "Bachelor's", institution: "XYZ University" }],
expData: [{ position: "Software Engineer", company: "ABC Corp" }],
summaryText: "Passionate about software development...",
skills: ["JavaScript", "React", "[Link]"],
selectedTemplate: selectedTemplate // 'template1' or 'template2'
};

try {
const response = await fetch('[Link] {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: [Link](resumeData),
});

if ([Link]) {
const blob = await [Link]();
const link = [Link]('a');
[Link] = [Link](blob);
[Link] = '[Link]';
[Link]();
} else {
[Link]('Failed to generate PDF');
}
} catch (error) {
[Link]('Error:', error);
}
};

Common questions

Powered by AI

The 'selectedTemplate' variable determines which HTML template is used to structure the resume data before it's rendered as a PDF. The availability of multiple templates allows the application to dynamically choose between different design layouts based on user input, enhancing flexibility in presentation. This capacity to switch layouts without altering the underlying data model allows users to tailor the visual style of the output document to suit different personal or business requirements effectively, thus broadening the application’s use case scenarios .

On the server side, error handling is managed within a try-catch block surrounding the HTML rendering and PDF generation logic. If an exception occurs, an error message is logged to the console, and a 500 status response is sent back with a failure message. On the client side, similar try-catch blocks are used; if the server does not respond with success, an error message is printed to the console. While these strategies effectively catch and log errors, they don't provide specific feedback on the nature of the errors to the end-user, which limits their effectiveness in guiding user remediation .

Error logging in the server code is primarily done using console.error statements, which show when PDF generation fails. While this provides basic debugging information, it could be enhanced by integrating a structured logging framework like Winston or using services like Loggly for centralized, persistent log storage. This would allow for better log categorization, real-time alerting, and historical analysis, helping developers quickly diagnose issues and improve maintenance efficiency .

'Template1' uses Arial as the font and has a standard margin with sections for education, experience, skills, and summary. It emphasizes simple presentation using default list styles for skills. In contrast, 'template2' employs 'Times New Roman', with centered headers and a list format for skills that include strong and emphasized text for degrees and positions. These style differences enhance the visual appeal and formal presentation of the PDF, catering to different aesthetic or professional preferences .

Security risks include data interception during transmission, unauthorized access to the server, and execution of arbitrary code within the server's context. Mitigation strategies include using HTTPS to encrypt data transmission, implementing authentication and authorization processes, ensuring input data is validated and sanitized to prevent injection attacks, and potentially running Puppeteer within isolated environments to minimize damage from security breaches. These measures would help mitigate risks associated with handling sensitive user data and ensure system integrity .

The current setup leverages Puppeteer, which can be resource-intensive as it involves launching headless Chrome instances. To scale, implementing a queue system to handle requests could ensure that browser instances are launched only when resources are available, avoiding memory exhaustion. Further optimizations might include deploying multiple service instances behind a load balancer, containerization with tools like Docker, and possibly using a serverless architecture to handle spikes in demand efficiently. This would require changes in infrastructure but would significantly enhance the system's capacity to handle higher volumes of requests .

The Express application serves as a back-end service for handling HTTP requests, specifically to generate PDF files from HTML content. Puppeteer is used in this context as a headless browser to render HTML into a PDF format. When a POST request is sent to the '/generate-pdf' endpoint, the server receives data including personal and professional information, which it then uses to create an HTML representation of a resume. Puppeteer processes this HTML by launching a browser instance, rendering the page, and generating a PDF from it, which is then returned as the response .

A possible feature enhancement could include providing real-time previews of the PDF before final generation. This feature would require additional frontend implementation to render HTML as a PDF-like preview within the browser using tools such as PDF.js. It would also necessitate backend adaptations to support repeated generation without launching a full Puppeteer instance each time until final generation, enhancing resource efficiency. This feature could significantly boost user satisfaction by allowing iterations and confirmations before committing to the final PDF output .

React is used on the client side to manage the resume's user interface and collect data via controlled inputs like 'ReactQuill', which is then sent to the server-side Express application through a POST request. The Express application processes the data, selects the appropriate HTML template, and uses Puppeteer to generate the PDF document. This division between front-end and back-end allows for real-time, dynamic user interaction and a robust server-side processing capability, combining the advantages of client-side reactivity and server-side power .

CSS in the HTML templates dictates the visual styling of the PDF output, affecting aspects like font choice, margins, text alignment, and list styles. Changes to the CSS can significantly alter how information is visually presented in the PDF, impacting readability, professionalism, and user preference. For example, modifying fonts or margins can make the document appear more formal or contemporary, which might be crucial for different contexts like academic versus creative fields. Therefore, controlling CSS directly influences user satisfaction with the resulting PDF design .

You might also like