Search code examples
javaapache-poilandscape-portraitorientation-changesxwpf

How to set page orientation for Word document?


I use Apache POI XWPF to create and handle MS Word documents. But I didn't find in the documentation how to change the page orientation.

Apparently this way should make it:

XWPFDocument doc = new XWPFDocument();

CTDocument1 document = doc.getDocument();
CTBody body = document.getBody();

if (!body.isSetSectPr()) {
     body.addNewSectPr();
}
CTSectPr section = body.getSectPr();

if(!section.isSetPgSz()) {
    section.addNewPgSz();
}
CTPageSz pageSize = section.getPgSz();

pageSize.setOrient(STPageOrientation.LANDSCAPE);

But this method doesn't work properly. I can set the page orientation to landscape, and when I read the page orientation in the code, I get landscape. All right. But if I open the saved document I've portrait format. This setting doesn't work in fact. What could be the problem?

As a workaround, I'm forced to start work with a blank document created manually in landscape or portrait format. But I want to create documents programmatically from scratch in needed orientation.

For instance POI HSSF and XSSF have functionality to toggle between landscape and portrait mode. It's setLandscape() method of org.apache.poi.ss.usermodel.PrintSetup interface.

But what about XWPF or HWPF?


Solution

  • You were very much on the right path. Setting the orientation to landscape describes the general orientation of the paper, but will still need the size of the paper. Your CTPageSz object doesn't have that yet.

    This means in addition to your setOrient call, you'll need to both setW and setH. These calls take BigIntegers that are representative of 1/20 Point. For a landscaped LETTER type paper therefore, you'll just:

    pageSize.setW(BigInteger.valueOf(15840));
    pageSize.setH(BigInteger.valueOf(12240));
    

    For Word to recognize it as Landscaped, the width must be greater than the height. You still want to keep the setOrient call as well if you want it to behave properly when going to print.

    Here's some common paper sizes in points from https://www.gnu.org/software/gv/manual/html_node/Paper-Keywords-and-paper-size-in-points.html you should take these and multiply them by twenty to use in the above method calls

    Letter       612x792
    LetterSmall  612x792
    Tabloid      792x1224
    Ledger       1224x792
    Legal        612x1008
    Statement    396x612
    Executive    540x720
    A0           2384x3371
    A1           1685x2384
    A2           1190x1684
    A3           842x1190
    A4           595x842
    A4Small      595x842
    A5           420x595
    B4           729x1032
    B5           516x729
    Folio        612x936
    Quarto       610x780
    10x14        720x1008