0

I am trying to build a table. I need the space between 2 rows to be reduced but I am not able to achieve the result using row.setheight().

Below is the code :

import eu.europa.ec.fisheries.quotaprepservice.constants.StrConstants;
import eu.europa.ec.fisheries.quotaprepservice.report.bean.Annexe1ATacBeanQuotaItem;
import eu.europa.ec.fisheries.quotaprepservice.report.bean.TacBean;
import org.apache.logging.log4j.util.Strings;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.List;

import static eu.europa.ec.fisheries.quotaprepservice.constants.StrConstants.*;

public class WordBuilder1 {
    public static void main(String[] args) throws Exception {
        XWPFDocument document = new XWPFDocument();
        XWPFParagraph paragraph = document.createParagraph();
        XWPFRun run = paragraph.createRun();
        run.setText("The table:");
        XWPFTable table = document.createTable(4, 8);
        prepareQuotaList(table);
        CTSectPr sectPr = document.getDocument().getBody().getSectPr();
        if (sectPr == null) sectPr = document.getDocument().getBody().addNewSectPr();
        CTPageSz pageSz = sectPr.addNewPgSz();
        pageSz.setOrient(STPageOrientation.PORTRAIT);
        pageSz.setW(BigInteger.valueOf(11900)); //12240 Twips = 12240/20 = 612 pt = 612/72 = 8.5"
        pageSz.setH(BigInteger.valueOf(16840)); //15840 Twips = 15840/20 = 792 pt = 792/72 = 11"

        FileOutputStream out = new FileOutputStream("C:\\Users\\mishrne\\example.docx");
        document.write(out);
        out.close();
    }

    private static void prepareQuotaList(XWPFTable table) {
        int count = 0;
        for (int row = 0; row < 4; row++) {
            XWPFTableRow tableRow = table.getRow(row);
            tableRow.setHeight((short) 0);
            for (int col = 0; col < 3; col++) {
                setCellBorders(tableRow.getCell(col), new STBorder.Enum[]{STBorder.NIL, STBorder.NIL, STBorder.NIL, STBorder.NIL});
            }
            setCellBorders(tableRow.getCell(3), new STBorder.Enum[]{STBorder.NIL, STBorder.NIL, STBorder.NIL, STBorder.NIL});
            setCellBorders(tableRow.getCell(4), new STBorder.Enum[]{STBorder.NIL, STBorder.NIL, STBorder.NIL, STBorder.NIL});
            for (int col = 5; col < 8; col++) {
                setCellBorders(tableRow.getCell(col), new STBorder.Enum[]{STBorder.NIL, STBorder.NIL, STBorder.NIL, STBorder.NIL});
            }
            if (count == 2) {
                createCell(tableRow.getCell(0), TAC, ParagraphAlignment.LEFT, 9);
                createCell(tableRow.getCell(2), "80", "(2)", ParagraphAlignment.RIGHT);
            } else {
                createCell(tableRow.getCell(0), "Belgium", ParagraphAlignment.LEFT, 9);
                mergeCellHorizontally(table, row, 2, 3);
                createCell(tableRow.getCell(2), "80", "(2)", ParagraphAlignment.RIGHT);
            }
            count++;
        }
    }

    private static void createCell(XWPFTableCell cell, String text, ParagraphAlignment paragraphAlignment, int fontSize) {
        XWPFParagraph paragraph = (cell.getParagraphs().size() > 0) ? cell.getParagraphs().get(0) : cell.addParagraph();
        paragraph.setIndentationLeft(5 * 20); // 10pt left indentation
        paragraph.setAlignment(paragraphAlignment);
        paragraph.setWordWrapped(true);
        XWPFRun run = (paragraph.getRuns().size() > 0) ? paragraph.getRuns().get(0) : paragraph.createRun();
        run.setText(text);
        run.setFontFamily(TIMES_NEW_ROMAN);
        run.setFontSize(fontSize);
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    }

    private static void createCell(XWPFTableCell cell, String text, String superscriptText, ParagraphAlignment left) {
        XWPFRun run;
        XWPFParagraph paragraph = (cell.getParagraphs().size() > 0) ? cell.getParagraphs().get(0) : cell.addParagraph();
        paragraph.setIndentationLeft(5 * 20); // 10pt left indentation
        paragraph.setAlignment(ParagraphAlignment.LEFT);
        paragraph.setSpacingBefore(0);
        paragraph.setSpacingBeforeLines(0);
        run = (paragraph.getRuns().size() > 0) ? paragraph.getRuns().get(0) : paragraph.createRun();
        run.setFontFamily(TIMES_NEW_ROMAN);
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        run.setFontSize(9);
        run.setText(text);
        run = paragraph.createRun();
        run.setText(StrConstants.BLANK_SPACE + StrConstants.BLANK_SPACE + StrConstants.BLANK_SPACE + superscriptText);
        run.setFontSize(9);
        run.setFontFamily(TIMES_NEW_ROMAN);
        run.setSubscript(VerticalAlign.SUPERSCRIPT); // superscript (2)
    }

    private static void mergeCellHorizontally(XWPFTable table, int row, int fromCol, int toCol) {
        XWPFTableCell cell = table.getRow(row).getCell(fromCol);
        CTTcPr tcPr = cell.getCTTc().getTcPr();
        if (tcPr == null) tcPr = cell.getCTTc().addNewTcPr();
        if (tcPr.isSetGridSpan()) {
            tcPr.getGridSpan().setVal(BigInteger.valueOf(toCol - fromCol + 1));
        } else {
            tcPr.addNewGridSpan().setVal(BigInteger.valueOf(toCol - fromCol + 1));
        }
        for (int colIndex = toCol; colIndex > fromCol; colIndex--) {
            table.getRow(row).getCtRow().removeTc(colIndex);
            table.getRow(row).removeCell(colIndex);
        }
    }

    private static void setCellBorders(XWPFTableCell cell, STBorder.Enum[] borderTypesLTRB) {
        CTTcBorders borders = CTTcBorders.Factory.newInstance();
        borders.addNewLeft().setVal(borderTypesLTRB[0]);
        borders.addNewTop().setVal(borderTypesLTRB[1]);
        borders.addNewRight().setVal(borderTypesLTRB[2]);
        borders.addNewBottom().setVal(borderTypesLTRB[3]);
        CTTcPr tcPr = cell.getCTTc().getTcPr();
        if (tcPr != null) {
            tcPr.setTcBorders(borders);
        } else {
            tcPr = CTTcPr.Factory.newInstance();
            tcPr.setTcBorders(borders);
            cell.getCTTc().setTcPr(tcPr);
        }
    }

}
theduck
  • 2,589
  • 13
  • 17
  • 23
Misthi
  • 33
  • 10
  • 1
    Too much code is just as unhelpful as no code. Please read [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). Then reduce the provided code to only show the problem you wants solving now. Hint: To set table row height in `XWPFTable table` the height rule also must be set additional to the height itself. For example: `table.getRow(0).setHeight(28*20); // 28pt row height` and `table.getRow(0).getCtRow().getTrPr().getTrHeightArray(0).setHRule(STHeightRule.EXACT);`. – Axel Richter Nov 20 '19 at 09:18
  • Thank you for your reply , the above solution table.getRow(0).setHeight(28*20); is not being helpful for my situation , the table height is not updating. And the second solution table.getRow(0).getCtRow().getTrPr() is throwing null pointer exception and i am not sure how can i fixed that. – Misthi Nov 20 '19 at 10:25
  • I kept the code so that it would be easy to understand the entire issue which i am facing and it is a good practice if we share compile free code .I will try to reduce the size for the code – Misthi Nov 20 '19 at 10:27

1 Answers1

1

To set table row height in XWPFTable table the height rule also must be set additional to the height itself. For example:

table.getRow(0).setHeight(12*20); // row height in twentieth pt
table.getRow(0).getCtRow().getTrPr().getTrHeightArray(0).setHRule(STHeightRule.EXACT); // height rule exact

There are following height rules possible:

AT_LEAST: At least the given height. Higher if needed but not lesser.

AUTO: The default. Default height of one default paragraph height inclusive spacing before and after. As high as needed dependent on content.

EXACT: Exact the given height. Content possibly gets cut of.

Note, a 0 value for XWPFTableRow.setHeight will not be accepted in combination with EXACT height rule. This falls back to default AUTO height then.

According to your code sample:

...
    private static void prepareQuotaList(XWPFTable table) {
        int count = 0;
        for (int row = 0; row < 4; row++) {
            XWPFTableRow tableRow = table.getRow(row);
            tableRow.setHeight(12*20); // row height = 12 pt
            tableRow.getCtRow().getTrPr().getTrHeightArray(0).setHRule(STHeightRule.EXACT); // height rule exact
            for (int col = 0; col < 3; col++) {
                setCellBorders(tableRow.getCell(col), new STBorder.Enum[]{STBorder.NIL, STBorder.NIL, STBorder.NIL, STBorder.NIL});
            }
...
    }
...

As said above there are only the three height rules possible. So if the goal is having table rows as high as their content but not more ore less, then height rule AUTO must be used. Then the paragraph's height determines the row height. Note a XWPFParagraph might have set spacing before, between and after the text rows. So you might have to set:

...
paragraph.setSpacingAfter(0);
paragraph.setSpacingBetween(1); // don't set this 0
paragraph.setSpacingBefore(0);
...

This must be set for each table cell which contains paragraphs already. So if needed for the whole table, then:

XWPFTable table = document.createTable(4, 8);
for (XWPFTableRow row : table.getRows()) {
 for (XWPFTableCell cell : row.getTableCells()) {
  for (XWPFParagraph p : cell.getParagraphs()) {
   p.setSpacingAfter(0);
   p.setSpacingBetween(1); // don't set this 0
   p.setSpacingBefore(0);
  }
 }
}
Axel Richter
  • 56,077
  • 6
  • 60
  • 87
  • Thanks for the reply but if the text is very big then it will break into next line and then as the height for the row is set ,the next line text will not be visible and ultimately i need to increase the height points which again lead to space between text. How can such scenarios can be handled with the above approach. – Misthi Nov 21 '19 at 08:55
  • @Neha Mishra: See my supplements. – Axel Richter Nov 21 '19 at 09:37