user12259208
user12259208

Reputation:

Need to reduce the spaces between 2 cells in apache poi word

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);
        }
    }

}

Upvotes: 0

Views: 1647

Answers (1)

Axel Richter
Axel Richter

Reputation: 61945

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);
  }
 }
}

Upvotes: 0

Related Questions