Electron - Generate dynamic docx documents from template

141 views Asked by At

I'm working on an electron application that will generate documents from a docx template. At the moment all seems working fine, but the client asked me a modification, he want to generate the documents dynamically, at the moment I have a static docx file that is loaded when the app is launched. The library I'm using for templating is easy-template-x and it will replace all the placeholders that are provided inside a docx document. At the moment the structure of the placeholders is less flexible and from the front end I'm passing a pre defined key value pair.

This is the vue front-end code

        addReceiver() {
            this.elencoDestinatari.push({
                data: new Date().toLocaleDateString('it'),
                ragioneSociale: this.ragioneSociale,
                indirizzo: this.indirizzo,
                comune: this.comune,
                pIva: this.pIva,
                nota: this.nota,
                email: this.email,
                oggettoComunicazione: this.oggettoComunicazione,
                corpoComunicazione: this.corpoComunicazione,
                ruoloMittente: this.ruoloMittente,
                firmaMittente: this.firmaMittente
            })
            window.ipcRenderer.send('showNotification', { type: 'receiverAdded' })
            this.clearReceiverFields()
        },

When all the data are in place I'm passing the array to the backend for processing

ipcMain.on('runProcess', async (event, ...args) => {
    let count = 0;
    let filesGenerated = false;
    const docData = JSON.parse(args[0]);
    const docPaths = [];
    const outputDocxDir = path.join(app.getPath('desktop'), `/MyApp-Docx-${Date.now()}`);
    const handler = new TemplateHandler({
        delimiters: {
            tagStart: '{',
            tagEnd: '}'
        }
    });
    //
    progressBar = new ProgressBar({
        indeterminate: false,
        text: 'MyApp',
        detail: 'Generazione documenti in corso...',
        abortOnError: true
    });
    //
    fs.mkdir( outputDocxDir )
        .then( async () => {
            const data = await fs.readFile('dependencies/PDFConverter.py');
            const pyFile = `${outputDocxDir}/PDFConverter.py`;
            fs.writeFile(pyFile, data)
                .then( () => {
                    console.log('File py creato con successo!');
                }).catch( (e) => {
                    throw e;
                });
        }).catch( (e) => {
            throw e;
        });
    //
    for( let i = 0; i < docData.length; i++ ) {
        
        const fileName = `${outputDocxDir}/myFile-${docData[i].ragioneSociale}.docx`;    
        
        handler.process(docTemplate, docData[i])
            .then( async (result) => {     
                await fs.writeFile(fileName, result)    
                const files = await fs.readdir( outputDocxDir );
                count++;
                if( count < 100 ) {
                    progressBar.value = count;
                }
                if( count === docData.length && files.length > 0 && files.length === docData.length + 1) {
                    filesGenerated = true;
                }
                if( filesGenerated ) {
                    const pyScript = childProcess.execFile('python', [`${outputDocxDir}/PDFConverter.py`], {
                        cwd: outputDocxDir
                    });
                    console.log(pyScript.pid);
                    pyScript.stdout.on('close', (code) => {
                        progressBar.value = 100;
                        popup.title = 'Multimailer';
                        popup.body = `${docData.length}`;
                        popup.show();
                        //dialog.showMessageBox({
                        //    title: 'MyApp',
                        //    message: 'Si desidera chiudere il programma?',
                        //    buttons: ['Si', 'No']
                        //}).then( (buttonsIndex) => {
                        //    if( buttonsIndex.response === 0 ) {
                        //        app.quit();
                        //    } else {
                        //        return;
                        //    }
                        //});
                    }); 
                    //const mailer = new MailComposer({
                    //    from: userCredentials.userMail,
                    //    to: docData[p].emailDestinatario,
                    //    subject: docData[p].oggetto,
                    //    text: docData[p].corpoComunicazione,
                    //    attachments: [
                    //        {
                    //            filename: `${outputDocxDir}/PDFs/${docData[i].nomeDestinatario}.${docData[i].luogoDestinatario}.pdf`,
                    //            path: docPaths[p]
                    //        }
                    //    ]
                    //})
                    //let composedMail = mailer.compile().build()
                    //gmail.users.messages.send({
                    //    userId: 'me',
                    //    resource: {
                    //      raw: composedMail,
                    //    },
                    //}).then( (messageId) => {
                    //    console.log(messageId)
                    //}).catch( (e) => { console.log(e) })
                }
            }).catch( (e) => {
                throw e;
            });
    }
});

Any suggestion on how I can avoid to have predefined fields for generating documents?

0

There are 0 answers