Search code examples
node.jsdocx

Generate docx table from 2-dimensional array in node js


I'm working with node.js and trying to generate a docx file with table based on 2-dimensional array, which length I don't know.

I found a few libraries for generating docx like: https://github.com/Ziv-Barber/officegen and https://github.com/open-xml-templating/docxtemplater. But the first doesn't support tables and the second (as far as I managed to understand) works only with objects.

So, is there any way to do such thing?


Solution

  • Disclaimer : I'm maintaining docxtemplater.

    It is possible to generate tables with arrays of data with docxtemplater, but as far as I can think of it, you can't use 2-dimensional arrays to output a table : eg the only way to loop in a table is looping to generate multiple rows.

    If you want to generate a table where you can have c columns and r rows, you can still use docxtemplater : If you use the {@rawXml} syntax, the document will replace that tag by some xml you put yourself.

    You should probably generate "tableXml" programmatically, with loops or a simple templating engine like mustache

    Your template could be for example:

    Customer {customer_name}
    
    {@tableXml}
    

    and your data:

    {
      customer_name:"Franck",
      tableXml:'<w:tbl>
      <w:tblPr>
        <w:jc w:val="left"/>
        <w:tblInd w:type="dxa" w:w="12"/>
        <w:tblBorders>
          <w:top w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
          <w:left w:val="nil"/>
          <w:bottom w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
          <w:insideH w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
          <w:right w:val="nil"/>
          <w:insideV w:val="nil"/>
        </w:tblBorders>
        <w:tblCellMar>
          <w:top w:type="dxa" w:w="0"/>
          <w:left w:type="dxa" w:w="108"/>
          <w:bottom w:type="dxa" w:w="0"/>
          <w:right w:type="dxa" w:w="108"/>
        </w:tblCellMar>
      </w:tblPr>
      <w:tblGrid>
        <w:gridCol w:w="1797"/>
        <w:gridCol w:w="2444"/>
        <w:gridCol w:w="2458"/>
        <w:gridCol w:w="1790"/>
      </w:tblGrid>
      <w:tr>
        <w:trPr>
          <w:cantSplit w:val="false"/>
        </w:trPr>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="1797"/>
            <w:tcBorders>
              <w:top w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:left w:val="nil"/>
              <w:bottom w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="4472C4" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style0"/>
              <w:tabs>
                <w:tab w:leader="none" w:pos="955" w:val="center"/>
              </w:tabs>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:b/>
                <w:bCs/>
                <w:color w:val="FFFFFF"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:b/>
                <w:bCs/>
                <w:color w:val="FFFFFF"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t>COLUMN1</w:t>
            </w:r>
          </w:p>
        </w:tc>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="2444"/>
            <w:tcBorders>
              <w:top w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:left w:val="nil"/>
              <w:bottom w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="4472C4" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style0"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:b/>
                <w:bCs/>
                <w:color w:val="FFFFFF"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:b/>
                <w:bCs/>
                <w:color w:val="FFFFFF"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t>COLUMN2</w:t>
            </w:r>
          </w:p>
        </w:tc>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="2458"/>
            <w:tcBorders>
              <w:top w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:left w:val="nil"/>
              <w:bottom w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="4472C4" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style0"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:b/>
                <w:bCs/>
                <w:color w:val="FFFFFF"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:b/>
                <w:bCs/>
                <w:color w:val="FFFFFF"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t>COLUMN3</w:t>
            </w:r>
          </w:p>
        </w:tc>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="1790"/>
            <w:tcBorders>
              <w:top w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:left w:val="nil"/>
              <w:bottom w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="4472C4" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style0"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:b/>
                <w:bCs/>
                <w:color w:val="FFFFFF"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:b/>
                <w:bCs/>
                <w:color w:val="FFFFFF"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t>COLUMN4</w:t>
            </w:r>
          </w:p>
        </w:tc>
      </w:tr>
      <w:tr>
        <w:trPr>
          <w:cantSplit w:val="false"/>
        </w:trPr>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="1797"/>
            <w:tcBorders>
              <w:top w:val="nil"/>
              <w:left w:val="nil"/>
              <w:bottom w:val="nil"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="FFFFFF" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style0"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t> #table1  t1data1 </w:t>
            </w:r>
          </w:p>
        </w:tc>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="2444"/>
            <w:tcBorders>
              <w:top w:val="nil"/>
              <w:left w:val="nil"/>
              <w:bottom w:val="nil"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="FFFFFF" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style32"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t> t1data2 </w:t>
            </w:r>
          </w:p>
        </w:tc>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="2458"/>
            <w:tcBorders>
              <w:top w:val="nil"/>
              <w:left w:val="nil"/>
              <w:bottom w:val="nil"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="FFFFFF" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style32"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t> t1data3 </w:t>
            </w:r>
          </w:p>
        </w:tc>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="1790"/>
            <w:tcBorders>
              <w:top w:val="nil"/>
              <w:left w:val="nil"/>
              <w:bottom w:val="nil"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="FFFFFF" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style32"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t> t1data4  /table1 </w:t>
            </w:r>
          </w:p>
        </w:tc>
      </w:tr>
      <w:tr>
        <w:trPr>
          <w:cantSplit w:val="false"/>
        </w:trPr>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="1797"/>
            <w:tcBorders>
              <w:top w:color="00000A" w:space="0" w:sz="6" w:val="double"/>
              <w:left w:val="nil"/>
              <w:bottom w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="FFFFFF" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style0"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:b/>
                <w:color w:val="00000A"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:b/>
                <w:color w:val="00000A"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t>TOTAL</w:t>
            </w:r>
          </w:p>
        </w:tc>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="2444"/>
            <w:tcBorders>
              <w:top w:color="00000A" w:space="0" w:sz="6" w:val="double"/>
              <w:left w:val="nil"/>
              <w:bottom w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="FFFFFF" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style32"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:b/>
                <w:color w:val="00000A"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:b/>
                <w:color w:val="00000A"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t> t1total1 </w:t>
            </w:r>
          </w:p>
        </w:tc>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="2458"/>
            <w:tcBorders>
              <w:top w:color="00000A" w:space="0" w:sz="6" w:val="double"/>
              <w:left w:val="nil"/>
              <w:bottom w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="FFFFFF" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style32"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:b/>
                <w:color w:val="00000A"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:b/>
                <w:color w:val="00000A"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t> t1total2 </w:t>
            </w:r>
          </w:p>
        </w:tc>
        <w:tc>
          <w:tcPr>
            <w:tcW w:type="dxa" w:w="1790"/>
            <w:tcBorders>
              <w:top w:color="00000A" w:space="0" w:sz="6" w:val="double"/>
              <w:left w:val="nil"/>
              <w:bottom w:color="00000A" w:space="0" w:sz="18" w:val="single"/>
              <w:right w:val="nil"/>
            </w:tcBorders>
            <w:shd w:fill="FFFFFF" w:val="clear"/>
          </w:tcPr>
          <w:p>
            <w:pPr>
              <w:pStyle w:val="style32"/>
              <w:spacing w:after="0" w:before="0" w:line="100" w:lineRule="atLeast"/>
              <w:contextualSpacing w:val="false"/>
              <w:jc w:val="center"/>
              <w:rPr>
                <w:b/>
                <w:color w:val="00000A"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:b/>
                <w:color w:val="00000A"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t> </w:t>
            </w:r>
            <w:bookmarkStart w:id="0" w:name="_GoBack2"/>
            <w:bookmarkEnd w:id="0"/>
            <w:r>
              <w:rPr>
                <w:b/>
                <w:color w:val="00000A"/>
                <w:lang w:val="en-US"/>
              </w:rPr>
              <w:t>t1total3 </w:t>
            </w:r>
          </w:p>
        </w:tc>
      </w:tr>
    </w:tbl>
    '
    }