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

Generated docx document.xml structure differs from Word - rendering Google Drive uploads incompatible #2712

Closed
gen3vra opened this issue Aug 15, 2024 · 7 comments

Comments

@gen3vra
Copy link

gen3vra commented Aug 15, 2024

If you export a simple table document with this library and attempt to upload it, it will be completely mangled. This can be fixed by changing literally anything and saving it in Word, thereby 'replacing' the document structure with a freshly saved Word generated one.

The problem lies in the document.xml structure. In other words, renaming both documents to .zip and extracting both, then replacing the 'broken' file's document.xml with the 'fixed' one will fix the broken one too.

The document.xml structure of the broken one
https://pastebin.com/raw/kaa3Erq5

The document.xml structure of the fixed one
https://pastebin.com/raw/mHn2QPK9

Here's an example of the broken docx upload
broken.docx
broken

And what it should look like after making a small edit (changing 'Test Text' -> 'Test Text (edit)'
fixed.docx
fixed

I'm unsure how to make default exported documents compatible with Google Drive from the get-go or what's causing this issue.

@anti-the-social
Copy link
Contributor

Hi!

TableCell needs width to be specified.
If that would not fully help, then add width for the Table too.

Not the first issue on that e.g. #1947
but there was some reasoning somewhere else. :)

BTW, which version of docxjs you use?

@gen3vra
Copy link
Author

gen3vra commented Aug 21, 2024

Appreciate your response.

This is an example of the top section.

schoolInformationSection = new docx.Table({
        width: {
            size: 100,
            type: docx.WidthType.PERCENTAGE,
        },
        rows: [
            new docx.TableRow({
                children: [
                    new docx.TableCell({
                        children: [
                            new docx.Paragraph({
                                children: [
                                    new docx.TextRun({
                                        text: "",
                                        font: "Arial",
                                        size: 20,
                                    }),
                                ],
                            }),
                        ],
                        width: {
                            size: 30,
                            type: docx.WidthType.PERCENTAGE,
                        },
                    }),
                    // Centered spacer
                    new docx.TableCell({
                        children: [
                            new docx.Paragraph({
                                children: [
                                    new docx.TextRun({
                                        text: "",
                                        font: "Arial",
                                        size: 20,
                                    }),
                                ],
                            }),
                        ],
                        width: {
                            size: 30,
                            type: docx.WidthType.PERCENTAGE,
                        },
                    }),
                    new docx.TableCell({
                        children: [
                            new docx.Paragraph({
                                children: [
                                    new docx.TextRun({
                                        text: schoolInfoName,
                                        font: "Arial",
                                        size: 20,
                                        bold: false
                                    }),
                                    ...schoolInfoAddressTextRuns,
                                ],
                                alignment: docx.AlignmentType.LEFT,
                            }),
                        ],
                        width: {
                            size: 40,
                            type: docx.WidthType.PERCENTAGE,
                        },
                    }),
                ],
            })
        ],
        borders: {
            top: {style: docx.BorderStyle.NONE, size: 0, color: "FFFFFF"},
            bottom: {style: docx.BorderStyle.NONE, size: 0, color: "FFFFFF"},
            left: {style: docx.BorderStyle.NONE, size: 0, color: "FFFFFF"},
            right: {style: docx.BorderStyle.NONE, size: 0, color: "FFFFFF"},
            insideHorizontal: {style: docx.BorderStyle.NONE, size: 0, color: "FFFFFF"},
            insideVertical: {style: docx.BorderStyle.NONE, size: 0, color: "FFFFFF"},
        },
    });
}

As far as I can tell, every section that should have a width set, does. Apparently the CDN I was using was on 7.1.0, but I upgraded to latest and it makes no difference. Here's the document.xml from the latest.
https://hastebin.skyra.pw/raw/nehalojisu (pastebin was under maintenance)

And an upload to docs.
broken

@anti-the-social
Copy link
Contributor

anti-the-social commented Aug 21, 2024

Oh yeah, if I remember correctly, Google docs does not support percentage very well, while standard Word does recalculate them into twips. (Thats why after opening in Word and re-saving would cure document for Google docs)

So for you, to support the platform you are looking for you would have to use absolute values.

@gen3vra
Copy link
Author

gen3vra commented Aug 21, 2024

What absolute values are those? Is there some sort of reference somewhere? What values correspond to 100% width of a normal Word document page?

@anti-the-social
Copy link
Contributor

anti-the-social commented Aug 22, 2024

Here is list of all width types
https://docx.js.org/api/variables/WidthType.html
DXA (Twips) is the absolute value which is 20points; while point is 0.75pixels; And there about 28.34646 points is one cm
Your width calculations would include page width minus margins.

So if width is 21cm and margins 2cm left and 2cm right its something like
(21-2-2)*28.34646*20

@anti-the-social
Copy link
Contributor

anti-the-social commented Aug 22, 2024

If I am not mistaken, width should be rounded number, so do not forget of Math.round()

@gen3vra
Copy link
Author

gen3vra commented Sep 7, 2024

Thank you

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

2 participants