Sascha B.
Sascha B.

Reputation: 70

Apache POI: How to set font style for a field (PAGE, PAGENUM, PAGEREF...)

From another (answered) question I learned how to add a page counter into a Word document. In addition I need to set the font family style (color, bold, italic, underline...) on the field (i.e. page counter). How can this be achieved?

CTSimpleField ctSimpleField = paragraph.getCTP().addNewFldSimple();

CTSimpleField does not provide methods to directly set these attributes.

Original question: How to add page numbers in format X of Y while creating a word document using apache poi api?

import java.io.*;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

public class CreateWordHeaderFooter {

 public static void main(String[] args) throws Exception {

  XWPFDocument doc= new XWPFDocument();

  // the body content
  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The Body:");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();  
  run.setText("Lorem ipsum.... page 1");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();
  run.addBreak(BreakType.PAGE); 
  run.setText("Lorem ipsum.... page 2");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();
  run.addBreak(BreakType.PAGE); 
  run.setText("Lorem ipsum.... page 3");

  // create header-footer
  XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
  if (headerFooterPolicy == null) headerFooterPolicy = doc.createHeaderFooterPolicy();

  // create header start
  XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = header.getParagraphArray(0);
  if (paragraph == null) paragraph = header.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.LEFT);

  run = paragraph.createRun();  
  run.setText("The Header:");

  // create footer start
  XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = footer.getParagraphArray(0);
  if (paragraph == null) paragraph = footer.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.CENTER);

  run = paragraph.createRun();  
  run.setText("Page ");
  // this adds the page counter
  paragraph.getCTP().addNewFldSimple().setInstr("PAGE \\* MERGEFORMAT");
  run = paragraph.createRun();
  run.setText(" of ");
  // this adds the page total number
  paragraph.getCTP().addNewFldSimple().setInstr("NUMPAGES \\* MERGEFORMAT");

  doc.write(new FileOutputStream("CreateWordHeaderFooter.docx"));

 }
}

Upvotes: 2

Views: 2325

Answers (1)

Axel Richter
Axel Richter

Reputation: 61852

To be able to formatting, we need runs in Word. But to create fields using runs we need three runs for each field. One run to mark the FldChar start, then one run to mark the fields InstrText and the third run to mark the FldChar end. And each run can, but also must, be formatted as needed.

Example:

import java.io.*;

import org.apache.poi.xwpf.usermodel.*;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;

public class CreateWordHeaderFooter {

 public static void main(String[] args) throws Exception {

  XWPFDocument doc= new XWPFDocument();

  // the body content
  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The Body:");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();  
  run.setText("Lorem ipsum.... page 1");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();
  run.addBreak(BreakType.PAGE); 
  run.setText("Lorem ipsum.... page 2");

  paragraph = doc.createParagraph();
  run=paragraph.createRun();
  run.addBreak(BreakType.PAGE); 
  run.setText("Lorem ipsum.... page 3");

  // create header-footer
  XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
  if (headerFooterPolicy == null) headerFooterPolicy = doc.createHeaderFooterPolicy();

  // create header start
  XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = header.getParagraphArray(0);
  if (paragraph == null) paragraph = header.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.LEFT);

  run = paragraph.createRun();  
  run.setText("The Header:");

  // create footer start
  XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);

  paragraph = footer.getParagraphArray(0);
  if (paragraph == null) paragraph = footer.createParagraph();
  paragraph.setAlignment(ParagraphAlignment.CENTER);

  run = paragraph.createRun();
  run.setBold(true);  
  run.setText("Page ");

  run = paragraph.createRun();  
  run.setBold(true); 
  run.getCTR().addNewFldChar().setFldCharType(org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType.BEGIN);

  run = paragraph.createRun(); 
  run.setBold(true); 
  run.getCTR().addNewInstrText().setStringValue("PAGE \\* MERGEFORMAT");

  run = paragraph.createRun();  
  run.setBold(true); 
  run.getCTR().addNewFldChar().setFldCharType(org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType.END);

  run = paragraph.createRun();  
  run.setBold(true); 
  run.setText(" of ");

  run = paragraph.createRun();  
  run.setBold(true); 
  run.getCTR().addNewFldChar().setFldCharType(org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType.BEGIN);

  run = paragraph.createRun();  
  run.setBold(true); 
  run.getCTR().addNewInstrText().setStringValue("NUMPAGES \\* MERGEFORMAT");

  run = paragraph.createRun();  
  run.setBold(true); 
  run.getCTR().addNewFldChar().setFldCharType(org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType.END);

  doc.write(new FileOutputStream("CreateWordHeaderFooter.docx"));

 }
}

Upvotes: 6

Related Questions