Multiplication Tables Generator (1–100)
Multiplication Tables Generator
Generate multiplication tables from 1 to 100
Table Settings
Display & Utilities
Generating Tables...
This may take a moment for large ranges
Generated Tables
0 tables
No tables generated yet
Configure your settings and click "Generate Tables"
');
printWindow.document.close();
}// Generate PDF - 16 tables per A4 page (4 rows × 4 columns)
async function generatePdf(tablesToGenerate = 'all', specificTable = null) {
showNotification('Generating PDF...');
try {
const { jsPDF } = window.jspdf;
const pdf = new jsPDF('portrait', 'mm', 'a4');
let tables = [];
if (tablesToGenerate === 'single' && specificTable) {
tables = state.tables.filter(t => t.number === specificTable);
} else {
tables = [...state.tables];
}
if (tables.length === 0) {
showNotification('No tables to generate PDF!');
return;
}
// PDF settings for A4 portrait
const pageWidth = 210; // A4 width in mm
const pageHeight = 297; // A4 height in mm
const margin = 10;
const contentWidth = pageWidth - 2 * margin;
const contentHeight = pageHeight - 2 * margin;
// Tables per page: 4 rows × 4 columns = 16 tables
const tablesPerPage = 16;
const tablesPerRow = 4;
const tablesPerCol = 4;
// Calculate table dimensions
const tableWidth = (contentWidth - (tablesPerRow - 1) * 5) / tablesPerRow;
const tableHeight = (contentHeight - 20 - (tablesPerCol - 1) * 5) / tablesPerCol;
// Split tables into pages
for (let page = 0; page < Math.ceil(tables.length / tablesPerPage); page++) {
const startIdx = page * tablesPerPage;
const endIdx = Math.min(startIdx + tablesPerPage, tables.length);
const pageTables = tables.slice(startIdx, endIdx);
// Start new page if not first page
if (page > 0) {
pdf.addPage();
}
// Add page title
pdf.setFontSize(16);
pdf.setTextColor(59, 130, 246);
pdf.text('Multiplication Tables', pageWidth / 2, margin + 8, { align: 'center' });
pdf.setFontSize(10);
pdf.setTextColor(100, 100, 100);
pdf.text(`Page ${page + 1} of ${Math.ceil(tables.length / tablesPerPage)}`, pageWidth / 2, margin + 14, { align: 'center' });
// Draw tables on this page
let tableIndex = 0;
for (let row = 0; row < tablesPerCol; row++) {
for (let col = 0; col < tablesPerRow; col++) {
if (tableIndex >= pageTables.length) break;
const tableData = pageTables[tableIndex];
const xPos = margin + col * (tableWidth + 5);
const yPos = margin + 20 + row * (tableHeight + 5);
// Draw table border
pdf.setDrawColor(200, 200, 200);
pdf.rect(xPos, yPos, tableWidth, tableHeight);
// Add table title
pdf.setFontSize(9);
pdf.setTextColor(59, 130, 246);
pdf.text(`Table of ${tableData.number}`, xPos + tableWidth / 2, yPos + 5, { align: 'center' });
// Add table content (2 columns of 5 rows each)
pdf.setFontSize(7);
pdf.setTextColor(0, 0, 0);
for (let i = 1; i <= 10; i++) {
const contentCol = i <= 5 ? 0 : 1;
const contentRow = i <= 5 ? i - 1 : i - 6;
const contentX = xPos + 5 + (contentCol * (tableWidth / 2));
const contentY = yPos + 10 + (contentRow * 6);
pdf.text(`${tableData.number} × ${i} =`, contentX, contentY);
pdf.text(`${tableData.number * i}`, contentX + (tableWidth / 2) - 8, contentY, { align: 'right' });
}
tableIndex++;
}
}
// Add footer to each page
pdf.setFontSize(8);
pdf.setTextColor(150, 150, 150);
pdf.text('Generated from: freetoolscraft.com', pageWidth / 2, pageHeight - margin, { align: 'center' });
}
// Save the PDF
const fileName = tablesToGenerate === 'single'
? `table-of-${specificTable}.pdf`
: `multiplication-tables-${new Date().toISOString().slice(0,10)}.pdf`;
pdf.save(fileName);
showNotification(`PDF downloaded successfully!`);
} catch (error) {
console.error('PDF generation error:', error);
showNotification('Error generating PDF. Using text fallback.');
// Fallback to text download
if (tablesToGenerate === 'single' && specificTable) {
downloadSingleText(specificTable);
} else {
downloadText();
}
}
}// Download single table as PDF
function downloadSinglePdf(tableNumber) {
generatePdf('single', tableNumber);
}// Download all tables as PDF
function downloadPdf() {
if (state.tables.length === 0) {
showNotification('No tables to download!');
return;
}
generatePdf('all');
}// Generate text content with website footer
function generateTextContent(tablesToGenerate = 'all', specificTable = null) {
let tables = [];
if (tablesToGenerate === 'single' && specificTable) {
tables = state.tables.filter(t => t.number === specificTable);
} else {
tables = [...state.tables];
}
let text = `MULTIPLICATION TABLES\n`;
text += `${'='.repeat(50)}\n`;
text += `Generated on: ${new Date().toLocaleDateString()}\n`;
text += `Total Tables: ${tables.length}\n`;
text += `${'='.repeat(50)}\n\n`;
// Generate each table separately
tables.forEach(tableData => {
text += `TABLE OF ${tableData.number}\n`;
text += `${'='.repeat(30)}\n`;
for (let i = 1; i <= 10; i++) {
text += `${tableData.number} × ${i} = ${tableData.number * i}\n`;
}
text += '\n';
});
// Add footer
text += `${'='.repeat(50)}\n`;
text += `Generated from: freetoolscraft.com\n`;
text += `${'='.repeat(50)}\n`;
return text;
}// Download all tables as text file
function downloadText() {
if (state.tables.length === 0) {
showNotification('No tables to download!');
return;
}
const text = generateTextContent('all');
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `multiplication-tables-${new Date().toISOString().slice(0,10)}.txt`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showNotification(`Text file with ${state.tables.length} tables downloaded!`);
}// Download single table as text
function downloadSingleText(tableNumber) {
const tableData = state.tables.find(t => t.number === tableNumber);
if (!tableData) return;
const text = generateTextContent('single', tableNumber);
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `table-of-${tableNumber}.txt`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showNotification(`Table of ${tableNumber} downloaded as text file!`);
}// Expand all tables
function expandAllTables() {
document.querySelectorAll('[data-table-number]').forEach(card => {
const cardBody = card.querySelector('div:nth-child(2)');
const toggleIcon = card.querySelector('.fa-chevron-down, .fa-chevron-up');
if (cardBody.classList.contains('hidden')) {
cardBody.classList.remove('hidden');
if (toggleIcon) {
toggleIcon.classList.remove('fa-chevron-down');
toggleIcon.classList.add('fa-chevron-up');
}
}
});
}// Collapse all tables
function collapseAllTables() {
document.querySelectorAll('[data-table-number]').forEach(card => {
const cardBody = card.querySelector('div:nth-child(2)');
const toggleIcon = card.querySelector('.fa-chevron-down, .fa-chevron-up');
if (!cardBody.classList.contains('hidden')) {
cardBody.classList.add('hidden');
if (toggleIcon) {
toggleIcon.classList.remove('fa-chevron-up');
toggleIcon.classList.add('fa-chevron-down');
}
}
});
}// Show notification
function showNotification(message) {
// Remove existing notification if any
const existingNotification = document.querySelector('.notification');
if (existingNotification) {
existingNotification.remove();
}
// Create notification element
const notification = document.createElement('div');
notification.className = 'notification fixed bottom-4 right-4 bg-gray-800 text-white px-4 py-3 rounded-lg shadow-lg z-50 transform translate-y-0 opacity-0 transition-all duration-300';
notification.textContent = message;
notification.style.backgroundColor = 'var(--primary-dark)';
document.body.appendChild(notification);
// Animate in
setTimeout(() => {
notification.classList.remove('opacity-0');
notification.classList.add('opacity-100');
}, 10);
// Remove after 3 seconds
setTimeout(() => {
notification.classList.remove('opacity-100');
notification.classList.add('opacity-0');
setTimeout(() => {
notification.remove();
}, 300);
}, 3000);
}// Initialize the app when DOM is loaded
document.addEventListener('DOMContentLoaded', init);