mirror of
https://github.com/alam00000/bentopdf.git
synced 2026-11-12 17:44:01 +01:00
feat: translate all pages, UI messages and docs and fix SEO redirects and indexing
This commit is contained in:
1 parent
5e019de5ae
commit
4edb1718cc
3344 files changed
+415643
-4759
No files matched your search
+71
-65
@@ -2,89 +2,95 @@ import { jsPDF } from 'jspdf';
|
||||
import autoTable from 'jspdf-autotable';
|
||||
import Papa from 'papaparse';
|
||||
|
||||
import { trText } from '../i18n/i18n.js';
|
||||
|
||||
export interface CsvToPdfOptions {
|
||||
onProgress?: (percent: number, message: string) => void;
|
||||
onProgress?: (percent: number, message: string) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a CSV file to PDF using jsPDF and autotable
|
||||
*/
|
||||
export async function convertCsvToPdf(
|
||||
file: File,
|
||||
options?: CsvToPdfOptions
|
||||
file: File,
|
||||
options?: CsvToPdfOptions
|
||||
): Promise<Blob> {
|
||||
const { onProgress } = options || {};
|
||||
const { onProgress } = options || {};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
onProgress?.(10, 'Reading CSV file...');
|
||||
return new Promise((resolve, reject) => {
|
||||
onProgress?.(10, trText('Reading CSV file...'));
|
||||
|
||||
Papa.parse(file, {
|
||||
complete: (results) => {
|
||||
try {
|
||||
onProgress?.(50, 'Generating PDF...');
|
||||
Papa.parse(file, {
|
||||
complete: (results) => {
|
||||
try {
|
||||
onProgress?.(50, trText('Generating PDF...'));
|
||||
|
||||
const data = results.data as string[][];
|
||||
const data = results.data as string[][];
|
||||
|
||||
// Filter out empty rows
|
||||
const filteredData = data.filter(row =>
|
||||
row.some(cell => cell && cell.trim() !== '')
|
||||
);
|
||||
// Filter out empty rows
|
||||
const filteredData = data.filter((row) =>
|
||||
row.some((cell) => cell && cell.trim() !== '')
|
||||
);
|
||||
|
||||
if (filteredData.length === 0) {
|
||||
reject(new Error('CSV file is empty'));
|
||||
return;
|
||||
}
|
||||
if (filteredData.length === 0) {
|
||||
reject(new Error(trText('CSV file is empty')));
|
||||
return;
|
||||
}
|
||||
|
||||
// Create PDF document
|
||||
const doc = new jsPDF({
|
||||
orientation: 'landscape', // Better for wide tables
|
||||
unit: 'mm',
|
||||
format: 'a4'
|
||||
});
|
||||
// Create PDF document
|
||||
const doc = new jsPDF({
|
||||
orientation: 'landscape', // Better for wide tables
|
||||
unit: 'mm',
|
||||
format: 'a4',
|
||||
});
|
||||
|
||||
// Extract headers (first row) and data
|
||||
const headers = filteredData[0];
|
||||
const rows = filteredData.slice(1);
|
||||
// Extract headers (first row) and data
|
||||
const headers = filteredData[0];
|
||||
const rows = filteredData.slice(1);
|
||||
|
||||
onProgress?.(70, 'Creating table...');
|
||||
onProgress?.(70, trText('Creating table...'));
|
||||
|
||||
// Generate table
|
||||
autoTable(doc, {
|
||||
head: [headers],
|
||||
body: rows,
|
||||
startY: 20,
|
||||
styles: {
|
||||
fontSize: 9,
|
||||
cellPadding: 3,
|
||||
overflow: 'linebreak',
|
||||
cellWidth: 'wrap',
|
||||
},
|
||||
headStyles: {
|
||||
fillColor: [41, 128, 185], // Nice blue header
|
||||
textColor: 255,
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
alternateRowStyles: {
|
||||
fillColor: [245, 245, 245], // Light gray for alternate rows
|
||||
},
|
||||
margin: { top: 20, left: 10, right: 10 },
|
||||
theme: 'striped',
|
||||
});
|
||||
|
||||
onProgress?.(90, 'Finalizing PDF...');
|
||||
|
||||
// Get PDF as blob
|
||||
const pdfBlob = doc.output('blob');
|
||||
|
||||
onProgress?.(100, 'Complete!');
|
||||
resolve(pdfBlob);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
// Generate table
|
||||
autoTable(doc, {
|
||||
head: [headers],
|
||||
body: rows,
|
||||
startY: 20,
|
||||
styles: {
|
||||
fontSize: 9,
|
||||
cellPadding: 3,
|
||||
overflow: 'linebreak',
|
||||
cellWidth: 'wrap',
|
||||
},
|
||||
error: (error) => {
|
||||
reject(new Error(`Failed to parse CSV: ${error.message}`));
|
||||
headStyles: {
|
||||
fillColor: [41, 128, 185], // Nice blue header
|
||||
textColor: 255,
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
});
|
||||
alternateRowStyles: {
|
||||
fillColor: [245, 245, 245], // Light gray for alternate rows
|
||||
},
|
||||
margin: { top: 20, left: 10, right: 10 },
|
||||
theme: 'striped',
|
||||
});
|
||||
|
||||
onProgress?.(90, trText('Finalizing PDF...'));
|
||||
|
||||
// Get PDF as blob
|
||||
const pdfBlob = doc.output('blob');
|
||||
|
||||
onProgress?.(100, trText('Complete!'));
|
||||
resolve(pdfBlob);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
reject(
|
||||
new Error(
|
||||
trText('Failed to parse CSV: {{error}}', { error: error.message })
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user