Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Word templates #14095

Open
barredterra opened this issue Jul 9, 2019 · 8 comments
Open

[Proposal] Word templates #14095

barredterra opened this issue Jul 9, 2019 · 8 comments

Comments

@barredterra
Copy link
Collaborator

Fill word templates with values from any document.

Add a new DocType Word Template with fields Title and related DocType.

Create a new Template

  1. Create a new Word Template and specify title and related doctype.
  2. Attach a .docx File to the Word Template

In the related DocType, a Button "Fill Word Template" will appear.

Fill a template:

  1. Open a document and click "Fill Word Template"
  2. Select a related Template
  3. All {{ var }} in the template will be replaced with field values from the document
  4. Attach the filled template to the document

https://github.com/elapouya/python-docx-template

@barredterra
Copy link
Collaborator Author

barredterra commented Jul 15, 2019

Implementation draft for server-side:

from six import BytesIO
from docxtpl import DocxTemplate

def _fill_template(template, data):
    """
    Fill a word template with data.

    Makes use of BytesIO to write the resulting file to memory instead of disk.

    :param template:    path to docx file or file-like object
    :param data:    dict with keys and values
    """
    doc = DocxTemplate(template)
    doc.render(data)
    _file = BytesIO()
    doc.docx.save(_file)
    return _file

@frappe.whitelist()
def fill_and_attach_template(doctype, name, template):
    """
    Use a documents data to fill a docx template and attach the result.

    Reads a document and a template file, fills the template with data from the
    document and attaches the resulting file to the document.

    :param doctype"     data doctype
    :param name"        data name
    :param template"    name of the template file
    """
    data = frappe.get_doc(doctype, name)
    data_dict = data.as_dict()

    template_doc = frappe.get_doc("File", template)
    template_path = template_doc.get_full_path()

    output_file = _fill_template(template_path, data_dict)
    output_doc = frappe.get_doc({
        "doctype": "File",
        "file_name": "-".join([name, template_doc.file_name]),
        "attached_to_doctype": doctype,
        "attached_to_name": name,
        "content": output_file.getvalue(),
    })
    output_doc.save()

Client side:

var dialog = new frappe.ui.Dialog({
    title: __('Choose a template file'),
    fields: [
        {
            fieldname: 'template',
            fieldtype: 'Link',
            label: 'File',
            options: 'File'
        },
    ],
    primary_action: () => {
        dialog.hide();
        frappe.call({
            method: "path.to.fill_and_attach_template",
            args: {
                doctype: frm.doc.doctype,
                name: frm.doc.name,
                template: dialog.get_values().template,
            },
            callback: (r) => frm.reload_doc(),
        });
    }
});
dialog.show();

@barredterra
Copy link
Collaborator Author

barredterra commented Nov 4, 2019

@rmehta:

We can have a "Print Format Type" property in print format that will export / preview on basis of the type... types like raw-printing / word / excel will have no preview of course.
The template in this case can be an attachment on the Print Format

Check with @karthikeyan5

@alkuhlani
Copy link

@barredterra
It's helpful, I tried it and it's brilliant.

I have a small ques, how we can deal with the child table.
Thank you in advance.

@nklyshko
Copy link

nklyshko commented Sep 1, 2021

Is this feature implemented now?

@barredterra
Copy link
Collaborator Author

@alkuhlani child tables should already work with the example code.

@CraftCoderr this has not been contributed to ERPNext yet. We have no motivation right now, but feel free to get it implemented by anyone, based on the example code. Implementation in ERPNext needs a bit of design work. I think Rushabh suggested that Word templates could be an extension of Print Format. Or you can make a custom app (quick and dirty).

@barredterra barredterra transferred this issue from frappe/erpnext Sep 1, 2021
@barredterra
Copy link
Collaborator Author

Transferred to frappe because Print Format belongs to the framework, not the ERP.

@Halmontaser
Copy link

this is a good propose just i have question since docxtpl is use jinja while frappe use jinja is this could make conflict since the different dependency could make conflict or it is normal

@barredterra
Copy link
Collaborator Author

True, if the Jinja versions are incompatible, it will not work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants
@nklyshko @alkuhlani @barredterra @Halmontaser and others