- Finalmente risolto il calcolo e l'impaginazione del PDF, per WEb e per Stampa (300 dpi) !

- corretto altre cose sulla lista cataloghi.
This commit is contained in:
Surya Paolo
2025-05-23 17:02:41 +02:00
parent d6aaaabb00
commit 0e5d28d199
6 changed files with 814 additions and 880 deletions

View File

@@ -19,6 +19,7 @@ mongoose.plugin(schema => {
const IElementiPagina = new Schema({ const IElementiPagina = new Schema({
isTemplate: Boolean, isTemplate: Boolean,
linkIdTemplate: String, linkIdTemplate: String,
linkIdTemplatePerStampa: String,
name: String, name: String,
pagina: IDimensioni, pagina: IDimensioni,
}); });
@@ -83,6 +84,7 @@ const catalogo = new Schema(
print_isTemplate: Boolean, print_isTemplate: Boolean,
print_linkIdTemplate: String, print_linkIdTemplate: String,
print_linkIdTemplatePerStampa: String,
dimensioni_def: IElementiPagina, dimensioni_def: IElementiPagina,

View File

@@ -116,6 +116,7 @@ const scheletroScheda = {
isTemplate: { type: Boolean }, isTemplate: { type: Boolean },
isPagIntro: { type: Boolean }, isPagIntro: { type: Boolean },
linkIdTemplate: { type: String }, linkIdTemplate: { type: String },
linkIdTemplatePerStampa: { type: String },
name: { type: String }, name: { type: String },
numschede_perRiga: { type: Number }, numschede_perRiga: { type: Number },
numschede_perCol: { type: Number }, numschede_perCol: { type: Number },

View File

@@ -136,18 +136,7 @@ function updateProductInfoCatProds(productInfo, reccatprod) {
} }
} }
} }
async function compressPdf(inputFile, outputFile, compressione) { /*
try {
const tempFolder = path.join(cwd, 'temp');
const hasTempFolder = await tools.isFileExistsAsync(tempFolder);
if (!hasTempFolder) {
console.log('creo directory', tempFolder);
await fs.mkdir(tempFolder); // Usa la versione promessa di mkdir
console.log('✅ directory creata', tempFolder);
}
/*
Quando utilizzi Ghostscript per comprimere un PDF e desideri controllare la qualità di stampa, puoi modificare i parametri dell'opzione -dPDFSETTINGS per ottenere risultati migliori per scopi di stampa. Quando utilizzi Ghostscript per comprimere un PDF e desideri controllare la qualità di stampa, puoi modificare i parametri dell'opzione -dPDFSETTINGS per ottenere risultati migliori per scopi di stampa.
Le seguenti opzioni sono disponibili per -dPDFSETTINGS: Le seguenti opzioni sono disponibili per -dPDFSETTINGS:
@@ -159,14 +148,49 @@ async function compressPdf(inputFile, outputFile, compressione) {
/default: Usa impostazioni predefinite; generalmente fornisce un buon equilibrio tra qualità e dimensione. /default: Usa impostazioni predefinite; generalmente fornisce un buon equilibrio tra qualità e dimensione.
*/ */
// Comprime il PDF utilizzando Ghostscript async function compressPdf(inputFile, outputFile, compressione) {
const gsCommand = `gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/${compressione} -dNOPAUSE -dQUIET -dBATCH -sOutputFile="${outputFile}" "${inputFile}"`; try {
const tempFolder = path.join(cwd, 'temp');
const hasTempFolder = await tools.isFileExistsAsync(tempFolder);
if (!hasTempFolder) {
console.log('creo directory', tempFolder);
await fs.mkdir(tempFolder); // Usa la versione promessa di mkdir
console.log('✅ directory creata', tempFolder);
}
// Valori ammessi per -dPDFSETTINGS di Ghostscript
const validSettings = ['screen', 'ebook', 'printer', 'prepress', 'default'];
if (!validSettings.includes(compressione)) {
console.warn(`Compressione '${compressione}' non valida, uso 'ebook'`);
compression = 'ebook';
}
// Costruisci comando Ghostscript per la compressione PDF
const gsCommand = [
'gs',
'-sDEVICE=pdfwrite',
'-dCompatibilityLevel=1.4',
`-dPDFSETTINGS=/${compressione}`,
'-dNOPAUSE',
'-dQUIET',
'-dBATCH',
`-sOutputFile="${outputFile}"`,
`"${inputFile}"`,
].join(' ');
console.log('Compressione del PDF in corso...');
console.log('gsCommand', gsCommand); console.log('gsCommand', gsCommand);
// Esegui il comando per la compressione // Esegui il comando per la compressione
await execPromise(gsCommand); await execPromise(gsCommand);
// Calcola la percentuale di compressione
const origSize = (await fs.promises.stat(inputFile)).size;
const newSize = (await fs.promises.stat(outputFile)).size;
const percent = Math.round(((origSize - newSize) / origSize) * 100);
console.log(`Il file compresso è circa il ${percent}% più piccolo dell'originale`);
console.log(`PDF compresso e salvato come '${outputFile}'`); console.log(`PDF compresso e salvato come '${outputFile}'`);
} catch (error) { } catch (error) {
console.error('Errore durante la compressione:', error); console.error('Errore durante la compressione:', error);
@@ -176,7 +200,7 @@ async function compressPdf(inputFile, outputFile, compressione) {
async function convertPDF_GS(inputFile, outputFile, width, height) { async function convertPDF_GS(inputFile, outputFile, width, height) {
// Verifica che il file di input esista // Verifica che il file di input esista
if (!await tools.isFileExistsAsync(inputFile)) { if (!(await tools.isFileExistsAsync(inputFile))) {
throw new Error(`Il file di input non esiste: ${inputFile}`); throw new Error(`Il file di input non esiste: ${inputFile}`);
} }
@@ -256,102 +280,16 @@ async function extractPdfInfo(inputFile) {
} }
async function convertPDF_PdfLib(idapp, inputFile, outputFile, options) { async function convertPDF_PdfLib(idapp, inputFile, outputFile, options) {
if (!await tools.isFileExistsAsync(inputFile)) { if (!(await tools.isFileExistsAsync(inputFile))) {
throw new Error(`Il file di input non esiste: ${inputFile}`); throw new Error(`Il file di input non esiste: ${inputFile}`);
} }
console.log('START convertPDF_PdfLib...'); console.log('START convertPDF_PdfLib...');
try { try {
// Carica il PDF esistente options.filenameIn = inputFile;
const existingPdfBytes = fs.readFileSync(inputFile); options.filenameOut = outputFile;
const pdfDoc = await PDFDocument.load(existingPdfBytes); const uscita = await ConvertPDF_Generatore(options, options.stampa);
// Crea un nuovo PDF
const newPdfDoc = await PDFDocument.create();
// Itera attraverso le pagine esistenti
const pages = pdfDoc.getPages();
for (const page of pages) {
const { width: originalWidth, height: originalHeight } = page.getSize();
// Calcola la larghezza e l'altezza in punti
const newWidth = options.width * 72; // Convertito in punti
const newHeight = options.height * 72; // Convertito in punti
// Crea una nuova pagina con le dimensioni specificate
const newPage = newPdfDoc.addPage([newWidth, newHeight]);
// Calcola lo scaling per mantenere le proporzioni
const scaleWidth = newWidth / originalWidth;
const scaleHeight = newHeight / originalHeight;
const scale = Math.min(scaleWidth, scaleHeight); // Usa il min per mantenere il rapporto
// Incorpora la pagina esistente nel nuovo PDF
const embeddedPage = await newPdfDoc.embedPage(page);
// Disegna la pagina incorporata nel nuovo PDF
newPage.drawPage(embeddedPage, {
x: (newWidth - originalWidth * scale) / 2, // Centrato orizzontalmente
y: (newHeight - originalHeight * scale) / 2, // Centrato verticalmente
width: originalWidth * scale,
height: originalHeight * scale,
});
}
let addstr = '';
if (options.compressione) {
addstr = '_temp.pdf';
}
// Salva il nuovo PDF
const pdfBytes = await newPdfDoc.save();
fs.writeFileSync(outputFile + addstr, pdfBytes);
console.log(`PDF convertito e salvato come '${outputFile}'`);
const comprimi = false;
const mostrainfo = true;
let fileout = outputFile;
if (options.compressione) {
const todayDate = tools.getDateYYYYMMDD_Today();
//const compressed = tools.removeFileExtension(outputFile) + `_${todayDate}.pdf`;
const compressed = tools.removeFileExtension(outputFile) + `_generato.pdf`;
await compressPdf(outputFile + addstr, compressed, options.compressione);
if (mostrainfo) extractPdfInfo(compressed);
fileout = compressed;
}
if (options.dir_out && options.idapp) {
// Crea directory se non esiste !
// Salva il fileout anche su questa directory dir_out
//const fileoutdir = path.join(options.dir_out, options.file_out);
//await fs.promises.copyFile(fileout, fileoutdir);
//console.log(`File ${fileout} anche salvato in ${options.dir_out}`);
}
let fileout_print = '';
// Crea anche il PDF per la stampa
if (
options.print_left !== 0 ||
options.print_top !== 0 ||
options.print_right !== 0 ||
options.print_bottom !== 0
) {
options.filenameIn = fileout;
ris = await ConvertPDF_WithMargins(options);
}
const uscita = {
pdf_generato: tools.removePathDirByFileName(options.idapp, fileout),
pdf_generato_stampa: tools.removePathDirByFileName(options.idapp, ris.fileout_print),
};
return uscita; return uscita;
} catch (e) { } catch (e) {
@@ -359,20 +297,56 @@ async function convertPDF_PdfLib(idapp, inputFile, outputFile, options) {
return ''; return '';
} }
} }
async function ConvertPDF_WithMargins(options) {
let fileout_print = '';
const marginTop = parseFloat(options.print_top) || 0; async function leggiDimensioniPdf(filePath) {
const marginRight = parseFloat(options.print_right) || 0; const pdfBytes = await fs.promises.readFile(filePath);
const marginBottom = parseFloat(options.print_bottom) || 0; const pdfDoc = await PDFDocument.load(pdfBytes);
const marginLeft = parseFloat(options.print_left) || 0;
const pages = pdfDoc.getPages();
const primaPagina = pages[0];
const { width, height } = primaPagina.getSize();
console.log(
`Dimensioni prima pagina: larghezza = ${tools.arrotondaA2Decimali(
(width / 72) * 25.4
)} mm, altezza = ${tools.arrotondaA2Decimali((height / 72) * 25.4)} mm`
);
return { width, height };
}
async function ConvertPDF_Generatore(options, instampa) {
let fileout = '';
let fileout_compressed = '';
let suffisso_filename = '';
if (!options.filenameIn) { if (!options.filenameIn) {
return { err: 'Nessun file caricato.' }; return { err: 'Nessun file passato in Ingresso.' };
} }
const outputFilename = path.basename(tools.removeFileExtension(options.filenameIn)) + '-stampabile.pdf'; let marginTop = instampa ? parseFloat(options.print_top) : 0;
const outputPath = path.join(options.dir_out, outputFilename); let marginRight = instampa ? parseFloat(options.print_right) : 0;
let marginBottom = instampa ? parseFloat(options.print_bottom) : 0;
let marginLeft = instampa ? parseFloat(options.print_left) : 0;
if (instampa) {
suffisso_filename = '-stampabile';
}
let outputFilename = suffisso_filename
? tools.aggiungiSuffissoAlNomeFile(options.filenameOut, suffisso_filename)
: options.filenameOut;
// controlla se outputFilename non ha directory allora gliela aggiungo
if (!path.dirname(outputFilename)) {
outputFilename = path.join(options.dir_out, outputFilename);
}
const outputFullPathFileName = outputFilename;
await leggiDimensioniPdf(options.filenameIn);
try { try {
// Leggi il PDF originale // Leggi il PDF originale
@@ -384,8 +358,12 @@ async function ConvertPDF_WithMargins(options) {
for (let i = 0; i < pages.length; i++) { for (let i = 0; i < pages.length; i++) {
const page = pages[i]; const page = pages[i];
// punti PDF (pt), dove 1 punto = 1/72 di pollice.
const { width, height } = page.getSize(); const { width, height } = page.getSize();
// CONVERTIli in mm e stampa su console
console.log(`Dimensione pagina ${i + 1}: ${(width / 72) * 25.4} mm x ${(height / 72) * 25.4} mm`);
const newWidth = width - marginLeft - marginRight; const newWidth = width - marginLeft - marginRight;
const newHeight = height - marginTop - marginBottom; const newHeight = height - marginTop - marginBottom;
@@ -408,18 +386,40 @@ async function ConvertPDF_WithMargins(options) {
// Salva il nuovo PDF // Salva il nuovo PDF
const pdfBytes = await destPdfDoc.save(); const pdfBytes = await destPdfDoc.save();
await fs.promises.mkdir(options.dir_out, { recursive: true }); const dirUscita = path.dirname(outputFullPathFileName);
if (!(await tools.isDirectoryAsync(dirUscita))) {
await fs.promises.mkdir(dirUscita, { recursive: true });
}
await fs.promises.writeFile(outputPath, pdfBytes); await fs.promises.writeFile(outputFullPathFileName, pdfBytes);
fileout_print = outputPath; fileout = outputFullPathFileName;
extractPdfInfo(fileout);
if (options.compressione) {
const mostrainfo = true;
// const todayDate = tools.getDateYYYYMMDD_Today();
//const compressed = tools.removeFileExtension(outputFile) + `_${todayDate}.pdf`;
fileout_compressed = tools.removeFileExtension(fileout) + `_compressed.pdf`;
await compressPdf(fileout, fileout_compressed, options.compressione);
// if (mostrainfo) extractPdfInfo(fileout_compressed);
}
} catch (error) { } catch (error) {
const log = 'Errore durante la creazione del PDF per la Stampa:' + error.message; const log = `Errore durante la creazione del PDF: (instampa = ${instampa}): ` + error.message;
console.error(log); console.error(log);
return { err: log, fileout_print: '' }; return {
err: log,
fileout: tools.removePathDirByFileName(options.idapp, fileout),
fileout_compressed: tools.removePathDirByFileName(options.idapp, fileout_compressed),
};
} }
return { fileout_print }; return {
fileout: tools.removePathDirByFileName(options.idapp, fileout),
fileout_compressed: tools.removePathDirByFileName(options.idapp, fileout_compressed),
};
} }
router.post('/online-pdf', authenticate, async (req, res) => { router.post('/online-pdf', authenticate, async (req, res) => {
@@ -605,76 +605,76 @@ router.post('/convert-pdf', upload.single('pdf'), async (req, res) => {
print_right = '0', print_right = '0',
print_bottom = '0', print_bottom = '0',
print_left = '0', print_left = '0',
stampa,
salvasufiledascaricare = 'false',
} = req.body; } = req.body;
if (!width) {
await fs.promises.unlink(inputFile);
return res.status(400).send('Width parameter is required');
}
const options = { const options = {
width, width,
height, height,
compressione, compressione,
dir_out, dir_out: tools.getdirByIdApp(idapp) + '/' + dir_out,
file_out, file_out,
idapp, idapp,
print_top, print_top,
print_right, print_right,
print_bottom, print_bottom,
print_left, print_left,
stampa: stampa === '1',
}; };
if (!width) { let invia_file_convertito = false;
fs.unlinkSync(inputFile); if (!options.file_out || options.file_out === '') {
return res.status(400).send('Width parameter is required'); options.file_out = `${tools.removeFileExtension(req.file.originalname)}-converted.pdf`;
invia_file_convertito = true;
} }
let outputFile = path.join(options.dir_out, options.file_out);
options.dir_out = tools.getdirByIdApp(options.idapp) + '/' + options.dir_out;
// let outputFile = path.join(options.dir_out, `${tools.removeFileExtension(req.file.originalname)}-converted.pdf`);
let outputFile = path.join(options.dir_out, `${options.file_out}`);
try { try {
await fs.promises.mkdir(DIR_PDF_IN, { recursive: true }); await fs.promises.mkdir(DIR_PDF_IN, { recursive: true });
await fs.promises.mkdir(options.dir_out, { recursive: true }); await fs.promises.mkdir(options.dir_out, { recursive: true });
// Converti il PDF // Converti il PDF
// await convertPDF_GS(inputFile, outputFile, width, height);
const risout = await convertPDF_PdfLib(idapp, inputFile, outputFile, options); const risout = await convertPDF_PdfLib(idapp, inputFile, outputFile, options);
if (!options.dir_out) { if (salvasufiledascaricare === 'true') {
// Invia il file convertito // Invia il file come download
res.download(risout.pdf_generato, 'output-converted.pdf', (err) => { return res.download(outputFile, options.file_out, async (err) => {
await cleanupFiles(inputFile, outputFile);
if (err) { if (err) {
if (err.code === 'ECONNABORTED' || err.code === 'ECONNRESET') {
console.warn('Richiesta annullata dal client:', err.message);
return;
}
console.error("Errore durante l'invio del file:", err.message || err); console.error("Errore durante l'invio del file:", err.message || err);
if (!res.headersSent) { if (!res.headersSent) {
res.status(500).send("Errore durante l'invio del file convertito"); res.status(500).send("Errore durante l'invio del file convertito");
} }
} else {
// Rimuovi i file temporanei
cleanupFiles(inputFile, '');
} }
}); });
} else { } else {
cleanupFiles(inputFile, ''); // Non inviare file, solo risposta JSON
await cleanupFiles(inputFile, ''); // pulisci solo inputFile
return res.status(200).send(risout);
} }
return res.status(200).send(risout);
} catch (error) { } catch (error) {
console.error('Errore durante la conversione:', error); console.error('Errore durante la conversione:', error);
cleanupFiles(inputFile, ''); await cleanupFiles(inputFile, '');
if (!res.headersSent) { if (!res.headersSent) {
res.status(500).send(`Errore durante la conversione del PDF: ${error.message}`); return res.status(500).send(`Errore durante la conversione del PDF: ${error.message}`);
} }
} }
}); });
function cleanupFiles(inputFile, outputFile) { async function cleanupFiles(inputFile, outputFile) {
if (inputFile) { if (inputFile) {
tools.deleteFile(inputFile).catch((err) => { await tools.deleteFile(inputFile).catch((err) => {
console.error('Errore durante la rimozione del file di INPUT:', err); console.error('Errore durante la rimozione del file di INPUT:', err);
}); });
} }
if (outputFile) { if (outputFile) {
tools.deleteFile(outputFile).catch((err) => { await tools.deleteFile(outputFile).catch((err) => {
console.error('Errore durante la rimozione del file di output:', err); console.error('Errore durante la rimozione del file di output:', err);
}); });
} }

File diff suppressed because it is too large Load Diff

View File

@@ -546,6 +546,15 @@ module.exports = {
FIRST_PROJ: '__PROJECTS', FIRST_PROJ: '__PROJECTS',
EXECUTE_CALCPROJ: true, EXECUTE_CALCPROJ: true,
isDirectoryAsync: async function (dir) {
try {
const stats = await fs.promises.stat(dir);
return stats.isDirectory();
} catch (e) {
return false;
}
},
isFileExistsAsync: async function (filename) { isFileExistsAsync: async function (filename) {
try { try {
let fileExists = await fs.promises let fileExists = await fs.promises
@@ -3999,33 +4008,40 @@ module.exports = {
async deleteFile(filePath) { async deleteFile(filePath) {
try { try {
await fs.promises.unlink(filePath); await fs.promises.unlink(filePath);
console.log(`File eliminato con successo: ${filePath}`); // console.log(`File eliminato con successo: ${filePath}`);
} catch (err) { } catch (err) {
console.error(`Errore durante l'eliminazione del file: ${filePath}`, err); console.error(`Errore durante l'eliminazione del file: ${filePath}`, err);
throw err; throw err;
} }
}, },
delete(mypath, alsothumb, callback) { async delete(mypath, alsothumb, callback) {
fs.unlink(mypath, function (err) { try {
if (alsothumb) { if (await this.isFileExistsAsync(mypath)) {
try { await fs.promises.unlink(mypath);
let img_small = path.dirname(mypath) + '/' + server_constants.PREFIX_IMG_SMALL + path.basename(mypath); // console.log(`deleted file ${mypath}`);
fs.unlink(img_small, function (err) { if (alsothumb) {
if (err) console.log('Errore durante la Cancellazione del file', mypath); let img_small = '';
else console.log('deleted file', mypath); try {
}); img_small = path.dirname(mypath) + '/' + server_constants.PREFIX_IMG_SMALL + path.basename(mypath);
} catch (e) { if (await this.isFileExistsAsync(img_small)) {
console.error(err); await fs.promises.unlink(img_small);
console.log(`deleted file ${img_small}`);
} else {
// console.warn(`File not found: ${img_small}`);
}
console.log(`deleted file ${img_small}`);
} catch (e) {
console.error(`Error deleting file ${img_small}`, e?.message);
}
} }
} }
if (err) { } catch (e) {
console.error(err); console.error(`Error deleting file ${mypath}`, e?.message);
callback(err); callback(e);
return; return;
} }
callback(); callback();
});
}, },
async mkdirpath(dirPath) { async mkdirpath(dirPath) {
@@ -5974,7 +5990,6 @@ module.exports = {
} }
} }
let fileesistente = false; let fileesistente = false;
if (productInfo.imagefile) { if (productInfo.imagefile) {
// controlla se esiste il file // controlla se esiste il file
@@ -6102,12 +6117,14 @@ module.exports = {
removePathDirByFileName(idapp, fullfilename) { removePathDirByFileName(idapp, fullfilename) {
const mydir = this.getdirByIdApp(idapp); const mydir = this.getdirByIdApp(idapp);
let filename = fullfilename.replace(mydir, '').replace(/\\/g, '/'); // Sostituisce backslash con slash
// ++ remove mydir from fullfilename and add myhost to generate a URL // Rimuove la barra iniziale se presente
const filename = fullfilename.replace(mydir, '').replace(/\\/g, '/'); // Replace backslashes with slashes if (filename.startsWith('/')) {
filename = filename.substring(1);
}
return filename; return filename;
}, },
isDateValid(mydate) { isDateValid(mydate) {
try { try {
return ( return (
@@ -6117,4 +6134,13 @@ module.exports = {
return false; return false;
} }
}, },
aggiungiSuffissoAlNomeFile(filePath, suffisso) {
const dir = path.dirname(filePath);
const estensione = path.extname(filePath);
const nomeFile = path.basename(filePath, estensione);
const nuovoNomeFile = nomeFile + suffisso + estensione;
return path.join(dir, nuovoNomeFile);
},
}; };

View File

@@ -1219,8 +1219,10 @@ module.exports = {
END_NORMALLY: 1, END_NORMALLY: 1,
END_WITHERROR: -50, END_WITHERROR: -50,
TOOLONGTIME: -10, TOOLONGTIME: -10,
} },
// Download, DVD, Epub, Mobi, Nuovo, PDF, Streaming, Usato // Download, DVD, Epub, Mobi, Nuovo, PDF, Streaming, Usato
PUNTI_PER_POLLICE: 96
}; };