Docx: Bugs found & some feature requests

Created on 5 Jan 2019  路  14Comments  路  Source: dolanmiu/docx

Hi there.

First of all: good job on v4.4 lately compared to version 3. We recently updated to v4 within our company and the v4.4 has a lot of new things and improvements. Unfortunately we came across some issues we really wonder why they're even documented because they do not seem to work.

We use this module _heavily_ within our company for one of our clients so we are getting the most out of it and we had to debug a lot in the core back then with v3 (also with v4 already) and within docx its XML files to see what was wrong. Below you'll find our feedback.

Some background information

  • We use this module in NodeJS.
  • We personally test using the latest version of LibreOffice on OS X. We also test on Microsoft Word 2007+ if a functionality is complete and finished for LibreOffice.

Bugs

Numbered lists

They seem to render almost correctly in the XML but it needs.. _something_. We're not sure what, but the problem is that the numbers do not show. However, bullets render correctly.

If I am using the jsfiddle provided in the README and adjust the code to be the code from this demo and use v4.4.1 it gives me this when I open it in libreoffice:

screenshot 2019-01-04 at 23 17 39

So the demo isn't working already, hence the fact it doesn't work for us. If this could be fixed that would be great.

Table of Contents

This was a huge add-on that we loved to see, unfortunately it doesn't work as well. Even when copying demos into the jsfiddle again, it still doesn't work. My colleague did the hard debugging for this one and mentioned that the XML doesn't generate the hyperlinking properly. Also, a related problem is that my document is not even recognizing the .heading1() as an actual heading. When I am looking in my overview of my document it says it has 0 headings, while it has multiple headings defined. This is probably the _main_ reason for the Table of Contents not being able to work.

Lists

A thing we would like to adjust ourselves is the option _"Don't add space between paragraphs of the same style"_ in a _"List Paragraph"_. I am seeing that this issue #222 is already marked as a _"Feature request"_ so I hope this will be implemented as well.

I have found the actual XML issue that causes this. The list items have in the xml xml:space="preserve" and this attribute will be removed when _"Don't add space between paragraphs of the same style"_ is checked. If you guys are able to implement this for _"ListParagraphs"_ that would be great!

screenshot 2019-01-04 at 23 38 00

Images

I do not believe this can be seen as a _bug_, but I do wonder whether this was done on purpose: I noticed images are being inserted with a default width/height of 100. We built our own custom wrapper function internally that uses the width/height of the image itself initially and also makes sure the image does not overlap the document by applying a scale-to-fit calculation when the image overlaps the document width (for now this is a constant variable and not taken from the document itself. If you do know how to get the width/height of the document, please comment down below. I would love to know this).

I really wonder what the reason is you guys don't use the image its width/height as default values. If those are not valid, then you can still go with the default value of 100, but it should have the image dimensions set correctly by default.

You can see our result below including source code (image 1 is twice the document size but nicely preserved and scaled down if it expands the document width, image 2 is smaller than the document width and thus rendered in its original size):

Scroll further to check the source code

screenshot 2019-01-04 at 23 54 00

This is how we calculate the image size (feel free to implement this)

const getImageSize = require('image-size');
const fs = require('fs');
const docx = require('docx');

/**
 * createResponsiveImage
 *
 * @description
 *   A wrapper function for the `docx.createImage()` function where we pass in
 *   the correct width/height params and prevent it from overlapping the
 *   document.
 *
 * @param {object} doc - The reference to the docx.Document() instance.
 * @param {string} imagePath
 * @return void
 */
function createResponsiveImage(doc, imagePath) {
  const docWidth = 600; // Any idea how to get this from the doc instance?
  const dimensions = getImageSize(imagePath);
  const width = parseInt(dimensions.width);
  const height = parseInt(dimensions.height);

  // Do a scale-to-fit calculation when the image is overlapping.
  const scale = width / docWidth;
  if (scale > 1) {
    doc.createImage(fs.readFileSync(imagePath), (width / scale), (height / scale));
  } else {
    doc.createImage(fs.readFileSync(imagePath), width, height);
  }
};

const doc = new docx.Document({
  title: '...',
  description: '...',
});

doc.createResponsiveImage = (imagePath) => createResponsiveImage(doc, imagePath);

// Usage
doc.createResponsiveImage('./path/to/image.png');

Feature requests

These are some things we think would be really nice to have:

  • Jump lists
  • Allow spacing for images (this is not possible, even when I am inserting it with a Paragraph coming from this demo)

I hope you can read all of the above and I would appreciate it if you could answer all my burning questions and give your opinion on all the bugs and its reasons + the future requests and whether these are doable or planned for in the future. We're planning to do some contributions based on your answer on this issue, but since we're really busy as well, we can't provide everything at once so help from you guys would be appreciated as well!

Thank you guys a lot for the hard work for this project! 馃 馃憤

Most helpful comment

Allow spacing for images (this is not possible, even when I am inserting it with a Paragraph coming from this demo)

4.6.0 now has this :)

https://github.com/dolanmiu/docx/blob/4.6.0/docs/usage/images.md

All 14 comments

Thanks for your kind words

Numbering

They seem to render almost correctly in the XML but it needs.. something. We're not sure what, but the problem is that the numbers do not show. However, bullets render correctly.

It seems like it works for me on master with https://github.com/dolanmiu/docx/blob/master/demo/demo3.ts:

image

Table of contents

This was a huge add-on that we loved to see, unfortunately it doesn't work as well. Even when copying demos into the jsfiddle again, it still doesn't work.

@sergiofm made this feature. Have you got any ideas bro?

Lists

A thing we would like to adjust ourselves is the option "Don't add space between paragraphs of the same style" in a "List Paragraph". I am seeing that this issue #222 is already marked as a "Feature request" so I hope this will be implemented as well.

Ok I will do this soon. Currently I am busy writing unit tests to bring the coverage level to 95%+! And then I am going to spend a lot of time documenting docx in https://docx.js.org.

Images

I do not believe this can be seen as a bug, but I do wonder whether this was done on purpose: I noticed images are being inserted with a default width/height of 100.

Yes this is not a bug. I initially used https://www.npmjs.com/package/image-size, which allowed each image to be correctly sized. It worked absolutely great! But the catch is, it does not work in the Browser environment. So I had to sadly ditch that idea. If you got any suggestions let me know

If you do know how to get the width/height of the document, please comment down below. I would love to know this)

Maybe it's this:

https://github.com/dolanmiu/docx/blob/master/src/file/document/body/section-properties/section-properties.ts#L57-L58

This is how we calculate the image size (feel free to implement this)
const getImageSize = require('image-size');

Haha, same method as me before 馃槈

Feature requests

Jump lists

Could you explain?

the future requests and whether these are doable or planned for in the future.

I need to check the OOXML spec to see if image margins/spacing are supported.

If you guys can contribute that would be really awesome!

Also, do you mind if I put your company on the front page of the README? And if so, which company?

Thanks again

Hi,

Thanks for the good comment! I tested again everything I came across but now on Microsoft Word 2007 because I myself am testing on LibreOffice. Everything is working as expected, so the issue here is support for LibreOffice.

I found out that LibreOffice is using OpenDocument as a standard instead of OpenOffice. It seems to be different in XML in some aspects. I understand that you won鈥檛 support everything so I will test on Microsoft Word. Our client is using Word as well and not LibreOffice. I personally thought they were equal in XML, but apparently not.

Which version of Microsoft Word do you seem to support? I presume 2008+ because our client wants 2007 as well. We can do this, but we noticed when the document contains an image the document is crashing in a Microsoft Word 2007 version. However if we open the same document in 2008 it is fixed. So what we did for now is removing images in 2007.

Tables

An issue I came across on 2007 is tables their width. It is the width of the columns, but tables should be 100% width. I did notice that you need to add <w:tblW w:w="5000" w:type="pct"/> which is required for 2007, like this:

<w:tbl>
    <w:tblPr>
        <w:tblW w:w="5000" w:type="pct"/> <!-- this one -->
    </w:tblPr>    
</w:tbl>

I do think the w:w is the document width - document margin? Not sure.

Bullets

Another question I had: how can I make nested bullets like this:

  • Lorem ipsum

    • Lorem ipsum

    • Lorem ipsum

  • Lorem ipsum

    • Lorem ipsum

  • Lorem ipsum

Numbering

It seems like it works for me on master with https://github.com/dolanmiu/docx/blob/master/demo/demo3.ts:

Works on Microsoft Word 2007+. The only thing that doesn't seem to work is formatting inside numbered lists. The following doesn't seem to work, atleast for 2007 (I haven't tested anything above):

...
const paragraph = new Paragraph("Hey you");
paragraph.setNumbering(concrete, 0);
const p = new docx.TextRun("Markup text here").italic().bold().underline();
paragraph.addRun(p);
doc.addParagraph(paragraph);
...

Table of Contents

Works on Microsoft Word 2007+, not on LibreOffice.

Images

Yes this is not a bug. I initially used https://www.npmjs.com/package/image-size, which allowed each image to be correctly sized. It worked absolutely great! But the catch is, it does not work in the Browser environment. So I had to sadly ditch that idea. If you got any suggestions let me know

It should be possible to get it somehow from buffer data so maybe we should look into a direction of where we get a Blob and convert it to a buffer to read out the image data. this module is doing this for NodeJS so let's see if we can find a multi-environment solution :)

I will do some research. It's fun to figure this one out so let me know as well if you got anything.

Maybe it's this:
https://github.com/dolanmiu/docx/blob/master/src/file/document/body/section-properties/section-properties.ts#L57-L58

It is! I managed to get this with: doc.Document.body.defaultSection.root[0].root[0].root, but this value is in 1/20th of an inch according to the OOXML documentation and the image its dimensions are in pixels so then we still have to convert both values (the image its pixels and the document its width/height) to a single unit.

Jump lists

Could you explain?

I believe the official term is "bookmark link" or "jump link" where you basically link text to a paragraph. Clicking on this will scroll to the actual content it is referring to. I have seen bookmarks somewhere in the code but not in the documentation yet. Maybe there is a demo of this? Are these _"bookmarks"_ the same I am talking about?

Also, do you mind if I put your company on the front page of the README? And if so, which company?

Personally I am fine by it, but I have to ask this at first. I'm working at an agency and we have a client that is using the docx-module so I assume it would be the client its company that will be in the README. I have to ask the client if he wants his company to be in the README. I'll let you know ;)

Thanks.

Yes you are right, I do not test on LibreOffice, only Microsoft Word for now. I am not sure of the precise version of word though. It seems like its 2008 then. Please make a PR if you know the cause of the weirdness in Libre and Word 2007!

Tables

I did notice that you need to add which is required for 2007

Interesting, so this is a bug then? docx should add a default width you mean?

Bullets

Look at https://github.com/dolanmiu/docx/blob/master/demo/demo3.ts

the .bullet(number) method. Where number is the indent level

Numbering

The only thing that doesn't seem to work is formatting inside numbered lists.

Strange. I have a feeling it's because the default styles are overriding the ones you set

Images

It is! I managed to get this with: doc.Document.body.defaultSection.root[0].root[0].root

I will expose this as a property of the Document as a convenience 馃槃

Jump lists

We call it Bookmarks. It does work. Check out this demo: https://github.com/dolanmiu/docx/blob/master/demo/demo21.ts

I have to ask the client if he wants his company to be in the README. I'll let you know ;)

Thanks 馃槃

@dolanmiu I also noticed that with the v4 you have an exposed API (woo-hoo!) but am I correct that we are able to insert things into the XML document ourself? If you can give a brief explanation about the API and what we can exactly do with this, that'd be great :)

Tables

Interesting, so this is a bug then? docx should add a default width you mean?

Exactly!

Bullets

Ah, thanks! I'll wait for the moment you update the documentation!

Numbering

Well, if you can provide me with an example that works, please do. If you can make a demo where lists are bold, italic etc (not the whole line, just a part of the text) that'd be great. Something like this:

  • Lorem ipsum _dor sit amet_

    • Lorem ipsum _dor_ sit amet

    • Lorem _ipsum dor_ sit amet

Additional info

We call it Bookmarks. It does work. Check out this demo: https://github.com/dolanmiu/docx/blob/master/demo/demo21.ts

Thanks!

I've never actually used that feature, its under ImportedXmlComponent. I will fiddle around with it soon. Wasn't me who wrote it

Numbering

I will try!

Regarding having borders around your images, it only works for Floating images. Inline images don't work:

The element can have a number of attributes related to the distance between the picture and the surrounding text. However, they have no effect when the picture is displayed inline. The attributes can be maintained and will have effect in the event that the picture is changed to be floating.

http://officeopenxml.com/drwPicInline.php

Allow spacing for images (this is not possible, even when I am inserting it with a Paragraph coming from this demo)

4.6.0 now has this :)

https://github.com/dolanmiu/docx/blob/4.6.0/docs/usage/images.md

@dolanmiu Thanks! Do you perhaps know if these things are possible:

  • Skip the first page when adding page numbers (so "page 1" is actually the second page)
  • Position an image at the bottom of a page. We want to be able to add an image on the first page where we have text in the middle and then an image on the bottom of that page. Also take note it should stay at the bottom of the page when the text gets longer. Is this possible?

Skip the first page when adding page numbers (so "page 1" is actually the second page)

I believe so. This feature is the title page, ill give an example later

Position an image at the bottom of a page. We want to be able to add an image on the first page where we have text in the middle and then an image on the bottom of that page. Also take note it should stay at the bottom of the page when the text gets longer. Is this possible?

Yes this is possible with floating images, and aligning it to the bottom of the page:

https://github.com/dolanmiu/docx/blob/master/demo/demo5.ts#L36

Take a look at demo 16 for your second query:

https://github.com/dolanmiu/docx/blob/master/demo/demo16.ts

I am going to improve the API. I am aware it is a bit of a hassle right now!

Numbering

The only thing that doesn't seem to work is formatting inside numbered lists.

Hi,
I'm trying the lowerLetter format, and I didn't get it.
Hoe can I do this?

Table of contents

This was a huge add-on that we loved to see, unfortunately it doesn't work as well. Even when copying demos into the jsfiddle again, it still doesn't work.

@sergiofm made this feature. Have you got any ideas bro?

Sorry by the late response. ToC are working great in Word 2013 and 2016, but it's not working in Libre Office, Word 2019 and Office 365.
I'll take a look at this feature to make it compatible at least with new versions of Word/Office.

Hi. Is there any fix or solution for images and Word 2007? Thanks

Closing as stale

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iainfreestone picture iainfreestone  路  3Comments

hmouhtar picture hmouhtar  路  6Comments

efx picture efx  路  5Comments

efx picture efx  路  6Comments

zahrafali picture zahrafali  路  5Comments