dolanmiu / docx

Easily generate and modify .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.
https://docx.js.org/
MIT License
4.36k stars 484 forks source link

DOCX does not apply the paragraph alignment to all merged cells in column #1219

Open tadmi opened 3 years ago

tadmi commented 3 years ago

I create a table in DOCX, apply center alignment to all cells. When select a table, in ms word interface can see the applied action:

image

When merging cells, the action applied to all cells is not displayed:

image

image

After manually applying alignment to the entire table from ms word interface: image

image

DOCX does not apply the settings (for example alignment) to the merged cells [except for the first main cell] (with a tag ).

anti-the-social commented 3 years ago

Seems to be a bug. Love the way you reported. Only thing that could be worth to add - little code that it can be run to reproduce the bug

tadmi commented 3 years ago

Only thing that could be worth to add - little code that it can be run to reproduce the bug

Good advice: the problem has narrowed. Bug is observed only when applying paragraph alignment in merged cells in a column.

Running code on Nodejs, DOCX 7.1.1.

const fs = require('fs');
const docx = require('docx');

const {
    Table,
    TableRow,
    TableCell,
    WidthType,
    AlignmentType,
    VerticalAlign,
    Document,
    Paragraph,
    Packer
} = docx;

const newParagraph = (parData) => {
    return new Paragraph({
        text: parData,
        alignment: AlignmentType.CENTER // here bug for merged cells in row: paragraph option does not apply to a cell that is part of the merged cells in row
    });
};

const newCell = (cellData = '', cellOps = {}) => {
    const { rowSpan, colSpan } = cellOps;

    return new TableCell({
        children: [newParagraph(cellData)],
        verticalAlign: VerticalAlign.CENTER,
        rowSpan: rowSpan || 1,
        columnSpan: colSpan || 1
    });
};

const newTableRow = (cells = []) => {
    const cellsArray = [];

    for (const cell of cells) {
        if (Array.isArray(cell)) {
            cellsArray.push(newCell(...cell));
        } else {
            cellsArray.push(newCell(cell));
        }
    }

    return new TableRow({
        children: cellsArray
    });
};

const newTable = (tableStructure = []) => {
    const tableRows = [];

    for (const tableRow of tableStructure) {
        tableRows.push(newTableRow(tableRow));
    }

    return new Table({
        rows: tableRows,
        width: {
            size: 5000,
            type: WidthType.PERCENTAGE
        }
    });
};

const table_noSpan = newTable([
    ['1', '2'],
    ['3', '4']
]);

const par_empty = newParagraph(' ');

// here bug for merged cells in row: paragraph option does not apply to a cell that is part of the merged cells in row
const table_rowSpan = newTable([[['1', { rowSpan: 2 }], '2'], ['4']]);

const table_colSpan = newTable([[['1', { colSpan: 2 }]], ['3', '4']]);

const doc = new Document({
    sections: [
        {
            children: [table_noSpan, par_empty, table_rowSpan, par_empty, table_colSpan]
        }
    ]
});

Packer.toBuffer(doc).then((buffer) => {
    fs.writeFileSync('document.docx', buffer);
});
jadenmazzone commented 2 years ago

I believe I'm running into the same issue which is that I'm unable to center paragraphs within row cells. Is there a fix?

PieceOfMeat commented 1 year ago

I found a (sloppy) workaround for this, was able to apply center alignment when set both alignment and heading fields on a paragraph. No luck in styling text after that though.