The core implementation requires including the jsPDF library and creating functions to handle text input and PDF generation.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Text to PDF Converter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.container {
display: flex;
flex-direction: column;
gap: 20px;
}
textarea {
width: 100%;
height: 300px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
}
button {
padding: 12px 20px;
background: #667eea;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background: #5568d3;
}
</style>
</head>
<body>
<div class="container">
<h1>Text to PDF Converter</h1>
<textarea id="text-input" placeholder="Enter your text here..."></textarea>
<button onclick="generatePDF()">Generate PDF</button>
</div>
<script>
function generatePDF() {
const { jsPDF } = window.jspdf;
const textInput = document.getElementById('text-input').value;
if (!textInput.trim()) {
alert('Please enter some text to convert.');
return;
}
const doc = new jsPDF();
doc.setFontSize(12);
const lines = doc.splitTextToSize(textInput, 180);
doc.text(lines, 10, 10);
doc.save('document.pdf');
}
</script>
</body>
</html>
Enhanced implementation with text formatting options, page settings, and custom styling capabilities.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Text to PDF Converter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
max-width: 900px;
margin: 0 auto;
padding: 20px;
background: #f5f7fa;
}
.container {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.controls {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-bottom: 20px;
}
.control-group {
display: flex;
flex-direction: column;
}
label {
margin-bottom: 5px;
font-weight: bold;
color: #333;
}
input, select {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
textarea {
width: 100%;
height: 350px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
font-family: inherit;
resize: vertical;
}
.button-group {
display: flex;
gap: 10px;
margin-top: 15px;
}
button {
padding: 12px 20px;
background: #667eea;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background: #5568d3;
}
.secondary-btn {
background: #6c757d;
}
.secondary-btn:hover {
background: #5a6268;
}
</style>
</head>
<body>
<div class="container">
<h1>Advanced Text to PDF Converter</h1>
<div class="controls">
<div class="control-group">
<label for="font-size">Font Size:</label>
<input type="number" id="font-size" value="12" min="8" max="72">
</div>
<div class="control-group">
<label for="page-size">Page Size:</label>
<select id="page-size">
<option value="a4">A4</option>
<option value="letter">Letter</option>
<option value="legal">Legal</option>
</select>
</div>
<div class="control-group">
<label for="orientation">Orientation:</label>
<select id="orientation">
<option value="portrait">Portrait</option>
<option value="landscape">Landscape</option>
</select>
</div>
<div class="control-group">
<label for="margin">Margin (mm):</label>
<input type="number" id="margin" value="10" min="5" max="50">
</div>
</div>
<textarea id="text-input" placeholder="Enter your text here..."></textarea>
<div class="button-group">
<button onclick="generatePDF()">Generate PDF</button>
<button class="secondary-btn" onclick="clearText()">Clear Text</button>
</div>
</div>
<script>
function generatePDF() {
const { jsPDF } = window.jspdf;
const textInput = document.getElementById('text-input').value;
if (!textInput.trim()) {
alert('Please enter some text to convert.');
return;
}
const fontSize = parseInt(document.getElementById('font-size').value);
const pageSize = document.getElementById('page-size').value;
const orientation = document.getElementById('orientation').value;
const margin = parseInt(document.getElementById('margin').value);
const doc = new jsPDF({
orientation: orientation,
unit: 'mm',
format: pageSize
});
doc.setFontSize(fontSize);
// Calculate available width for text
const pageWidth = doc.internal.pageSize.getWidth();
const availableWidth = pageWidth - (2 * margin);
// Split text into lines that fit the page width
const lines = doc.splitTextToSize(textInput, availableWidth);
// Add text to PDF with proper spacing
let yPosition = margin;
const lineHeight = (fontSize * 1.2) / 25.4 * 72; // Convert mm to points
for (let i = 0; i < lines.length; i++) {
if (yPosition > doc.internal.pageSize.getHeight() - margin) {
doc.addPage();
yPosition = margin;
}
doc.text(lines[i], margin, yPosition);
yPosition += lineHeight;
}
// Generate filename based on content
const filename = textInput.substring(0, 20).replace(/[^\w\s]/gi, '') || 'document';
doc.save(`${filename}.pdf`);
}
function clearText() {
document.getElementById('text-input').value = '';
}
</script>
</body>
</html>
Complete implementation with headers, footers, custom fonts, and multi-page support.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Complete Text to PDF Converter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
}
.container {
max-width: 1000px;
margin: 0 auto;
background: white;
padding: 40px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
h1 {
text-align: center;
color: #2c3e50;
margin-bottom: 30px;
}
.form-section {
margin-bottom: 30px;
}
.form-row {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-bottom: 15px;
}
.form-group {
flex: 1;
min-width: 200px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #34495e;
}
input, select, textarea {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
}
textarea {
min-height: 300px;
font-family: inherit;
resize: vertical;
}
.button-group {
display: flex;
gap: 15px;
flex-wrap: wrap;
margin-top: 20px;
}
button {
padding: 12px 25px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
font-weight: 600;
transition: all 0.3s ease;
}
.primary-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.primary-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}
.secondary-btn {
background: #6c757d;
color: white;
}
.secondary-btn:hover {
background: #5a6268;
transform: translateY(-2px);
}
.success-btn {
background: #28a745;
color: white;
}
.success-btn:hover {
background: #218838;
transform: translateY(-2px);
}
.info-box {
background: #e8f4fd;
border-left: 5px solid #2196F3;
padding: 15px;
margin: 20px 0;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="container">
<h1>Complete Text to PDF Converter</h1>
<div class="form-section">
<div class="form-row">
<div class="form-group">
<label for="document-title">Document Title:</label>
<input type="text" id="document-title" placeholder="Enter document title">
</div>
<div class="form-group">
<label for="author">Author:</label>
<input type="text" id="author" placeholder="Enter author name">
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="font-family">Font Family:</label>
<select id="font-family">
<option value="helvetica">Helvetica</option>
<option value="times">Times New Roman</option>
<option value="courier">Courier</option>
</select>
</div>
<div class="form-group">
<label for="font-size">Font Size:</label>
<input type="number" id="font-size" value="12" min="8" max="72">
</div>
<div class="form-group">
<label for="page-size">Page Size:</label>
<select id="page-size">
<option value="a4">A4</option>
<option value="letter">Letter</option>
<option value="legal">Legal</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="orientation">Orientation:</label>
<select id="orientation">
<option value="portrait">Portrait</option>
<option value="landscape">Landscape</option>
</select>
</div>
<div class="form-group">
<label for="margin">Margin (mm):</label>
<input type="number" id="margin" value="20" min="5" max="50">
</div>
<div class="form-group">
<label for="include-header">Include Header:</label>
<select id="include-header">
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</div>
</div>
</div>
<div class="form-group">
<label for="text-input">Text Content:</label>
<textarea id="text-input" placeholder="Enter your text content here..."></textarea>
</div>
<div class="button-group">
<button class="primary-btn" onclick="generatePDF()">Generate PDF</button>
<button class="secondary-btn" onclick="clearAll()">Clear All</button>
<button class="success-btn" onclick="previewPDF()">Preview PDF</button>
</div>
<div class="info-box">
<strong>💡 Tip:</strong> The converter supports multi-page documents. Large texts will automatically be split across multiple pages with proper margins and formatting.
</div>
</div>
<script>
function generatePDF() {
const { jsPDF } = window.jspdf;
const textInput = document.getElementById('text-input').value;
if (!textInput.trim()) {
alert('Please enter some text to convert.');
return;
}
const title = document.getElementById('document-title').value || 'Document';
const author = document.getElementById('author').value || 'Anonymous';
const fontFamily = document.getElementById('font-family').value;
const fontSize = parseInt(document.getElementById('font-size').value);
const pageSize = document.getElementById('page-size').value;
const orientation = document.getElementById('orientation').value;
const margin = parseInt(document.getElementById('margin').value);
const includeHeader = document.getElementById('include-header').value === 'yes';
const doc = new jsPDF({
orientation: orientation,
unit: 'mm',
format: pageSize
});
// Set document properties
doc.setProperties({
title: title,
author: author,
subject: 'Generated Document',
creator: 'Text to PDF Converter'
});
// Set font
doc.setFont(fontFamily);
doc.setFontSize(fontSize);
// Calculate available width for text
const pageWidth = doc.internal.pageSize.getWidth();
const availableWidth = pageWidth - (2 * margin);
// Add header if requested
if (includeHeader) {
doc.setFontSize(fontSize + 4);
doc.setFont(fontFamily, 'bold');
doc.text(title, pageWidth / 2, margin + 10, { align: 'center' });
doc.setFontSize(fontSize);
doc.setFont(fontFamily, 'normal');
doc.text(`Author: ${author}`, pageWidth / 2, margin + 18, { align: 'center' });
// Add date
const date = new Date().toLocaleDateString();
doc.text(`Date: ${date}`, pageWidth / 2, margin + 25, { align: 'center' });
doc.line(margin, margin + 30, pageWidth - margin, margin + 30); // Header separator
}
// Split text into lines that fit the page width
const lines = doc.splitTextToSize(textInput, availableWidth);
// Add text to PDF with proper spacing
let yPosition = includeHeader ? margin + 40 : margin + 10;
const lineHeight = (fontSize * 1.2) / 25.4 * 72; // Convert mm to points
for (let i = 0; i < lines.length; i++) {
if (yPosition > doc.internal.pageSize.getHeight() - margin) {
// Add page number to previous page
doc.setFontSize(10);
doc.text(`Page ${doc.internal.getNumberOfPages()}`, pageWidth / 2, doc.internal.pageSize.getHeight() - 10, { align: 'center' });
doc.addPage();
yPosition = margin + 10;
// Add header to new page if needed
if (includeHeader) {
doc.setFontSize(fontSize + 4);
doc.setFont(fontFamily, 'bold');
doc.text(title, pageWidth / 2, margin + 10, { align: 'center' });
doc.setFontSize(fontSize);
doc.setFont(fontFamily, 'normal');
doc.line(margin, margin + 15, pageWidth - margin, margin + 15);
yPosition = margin + 20;
}
}
doc.text(lines[i], margin, yPosition);
yPosition += lineHeight;
}
// Add page number to last page
doc.setFontSize(10);
doc.text(`Page ${doc.internal.getNumberOfPages()}`, pageWidth / 2, doc.internal.pageSize.getHeight() - 10, { align: 'center' });
// Generate filename based on title
const filename = title.replace(/[^\w\s]/gi, '') || 'document';
doc.save(`${filename}.pdf`);
}
function clearAll() {
document.getElementById('document-title').value = '';
document.getElementById('author').value = '';
document.getElementById('text-input').value = '';
}
function previewPDF() {
alert('PDF preview functionality would require additional implementation with PDF.js or similar library.');
}
</script>
</body>
</html>
Building a text to PDF converter using jsPDF provides a powerful client-side solution for document generation. The implementation offers significant advantages including immediate processing, reduced server load, and enhanced privacy. The basic implementation handles simple text conversion, while advanced features enable custom formatting, multi-page support, and professional document creation. The converter can be customized with various fonts, page sizes, margins, and styling options. Advanced implementations include headers, footers, page numbering, and document metadata. The solution is particularly valuable for creating reports, certificates, invoices, or any document requiring text-based content. The jsPDF library provides extensive documentation and community support for further customization. The converter can be integrated into existing web applications or deployed as a standalone tool. Performance considerations include text validation, size limits, and memory management for large documents. The implementation demonstrates modern web development practices with responsive design and user-friendly interfaces. This approach represents a cost-effective solution for document generation without server dependencies.