如何在poi word中设置内容表的字体样式,包括字体颜色,字体大小和粗体?

时间:2017-04-11 01:48:55

标签: apache-poi

我使用doc.createTOC();生成poi word(XWPF)中的内容表,并使用addCustomHeadingStyle(doc, ChapterLvl.LVL_1.style, 1);生成标题内容,虚线和页码。但我想设置不同的标题级别标题内容有不同的字体大小,字体颜色,粗体,虚线和页码具有相同的样式及其对应的标题内容,如图片附件,有人可以给我一些建议怎么做?

private static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {
        CTStyle ctStyle = CTStyle.Factory.newInstance();
        ctStyle.setStyleId(strStyleId);
        CTString styleName = CTString.Factory.newInstance();
        styleName.setVal(strStyleId);
        ctStyle.setName(styleName);
        CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
        indentNumber.setVal(BigInteger.valueOf(headingLevel));
        ctStyle.setUiPriority(indentNumber);
        CTOnOff onoffnull = CTOnOff.Factory.newInstance();
        ctStyle.setUnhideWhenUsed(onoffnull);
        ctStyle.setQFormat(onoffnull);
        CTPPr ppr = CTPPr.Factory.newInstance();
        ppr.setOutlineLvl(indentNumber);
        ctStyle.setPPr(ppr);
        XWPFStyle style = new XWPFStyle(ctStyle);
        XWPFStyles styles = docxDocument.createStyles();
        style.setType(STStyleType.PARAGRAPH);
        styles.addStyle(style);
    }

enter image description here

2 个答案:

答案 0 :(得分:1)

我甚至无法使用XWPFDocument.createTOC()获得有价值的结果(例如,页码字段是​​错误的)。所以我从未使用过它。我可以说的是XWPFDocument.createTOC()目前没有创建一个"目录"就像Word本身一样。因此,在Word中打开后,它将不会被Word GUI识别为TOC。

但如果问题只是关于风格,那么可以回答。必须有名为" toc 1"," toc 2"," toc 3",...," toc n"每个标题级别的目前。这可以使用XML来实现,如:

<w:style w:styleId="TOC1" w:type="paragraph">
 <w:name w:val="toc 1"/>
 <w:basedOn w:val="Normal"/>
 <w:next w:val="Normal"/>
 <w:autoRedefine/><w:unhideWhenUsed/>
 <w:rPr>
  <w:b/><w:bCs/><w:caps/><w:sz w:val="32"/><w:szCs w:val="32"/>
 </w:rPr>
</w:style>

最多格式化是在rPr (Run Properties)元素及其子元素内完成的。

示例:

import java.io.File;
import java.io.FileOutputStream;

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

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSimpleField;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;

import java.math.BigInteger;

public class CreateWordNumberedHeadings {

 static String cTAbstractNumDecimalXML = 
  "<w:abstractNum xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:abstractNumId=\"0\">"
+ "<w:multiLevelType w:val=\"hybridMultilevel\"/>"
+ "<w:lvl w:ilvl=\"0\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"360\" w:hanging=\"360\"/></w:pPr></w:lvl>"
+ "<w:lvl w:ilvl=\"1\" w:tentative=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%2\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"720\" w:hanging=\"360\"/></w:pPr></w:lvl>"
+ "<w:lvl w:ilvl=\"2\" w:tentative=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%2.%3\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1440\" w:hanging=\"360\"/></w:pPr></w:lvl>"
+ "</w:abstractNum>";

 static String cTStyleNormal =
  "<w:style xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\">" 
+ "<w:name w:val=\"Normal\"/>"
+ "<w:qFormat/>"
+ "</w:style>";
 static String cTStyleH1XML =
  "<w:style xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:type=\"paragraph\" w:styleId=\"Heading1\">"
+ "<w:name w:val=\"heading 1\"/>"
+ "<w:basedOn w:val=\"Normal\"/>"
+ "<w:next w:val=\"Normal\"/>"
+ "<w:unhideWhenUsed/>"
+ "<w:qFormat/>"
+ "<w:rPr><w:b/><w:sz w:val=\"36\"/></w:rPr>"
+ "</w:style>";
 static String cTStyleH2XML =
  "<w:style xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:type=\"paragraph\" w:styleId=\"Heading2\">"
+ "<w:name w:val=\"heading 2\"/>"
+ "<w:basedOn w:val=\"Normal\"/>"
+ "<w:next w:val=\"Normal\"/>"
+ "<w:unhideWhenUsed/>"
+ "<w:qFormat/>"
+ "<w:rPr><w:sz w:val=\"32\"/></w:rPr>"
+ "</w:style>";
 static String cTStyleH3XML =
  "<w:style xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:type=\"paragraph\" w:styleId=\"Heading3\">"
+ "<w:name w:val=\"heading 3\"/>"
+ "<w:basedOn w:val=\"Normal\"/>"
+ "<w:next w:val=\"Normal\"/>"
+ "<w:unhideWhenUsed/>"
+ "<w:qFormat/>"
+ "<w:rPr><w:i/><w:sz w:val=\"28\"/></w:rPr>"
+ "</w:style>";

static String cTStyleTOC1 =
  "<w:style xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:type=\"paragraph\" w:styleId=\"TOC1\">"
+ "<w:name w:val=\"toc 1\"/>"
+ "<w:basedOn w:val=\"Normal\"/>"
+ "<w:next w:val=\"Normal\"/>"
+ "<w:autoRedefine/><w:unhideWhenUsed/>"
+ "<w:rPr><w:b/><w:bCs/><w:caps/><w:sz w:val=\"32\"/><w:szCs w:val=\"32\"/></w:rPr>"
+ "</w:style>";

static String cTStyleTOC2 =
  "<w:style xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:type=\"paragraph\" w:styleId=\"TOC2\">"
+ "<w:name w:val=\"toc 2\"/>"
+ "<w:basedOn w:val=\"Normal\"/>"
+ "<w:next w:val=\"Normal\"/>"
+ "<w:autoRedefine/><w:unhideWhenUsed/>"
+ "<w:rPr><w:i/><w:iCs/><w:sz w:val=\"28\"/><w:szCs w:val=\"28\"/></w:rPr>"
+ "</w:style>";

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

  XWPFDocument document = new XWPFDocument();       

  XWPFNumbering numbering = document.createNumbering();
  CTNumbering cTNumbering = CTNumbering.Factory.parse(cTAbstractNumDecimalXML);
  CTAbstractNum cTAbstractNum = cTNumbering.getAbstractNumArray(0);
  XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum);

  BigInteger abstractNumID = numbering.addAbstractNum(abstractNum);
  BigInteger numID = numbering.addNum(abstractNumID);

  XWPFStyles styles = document.createStyles();
  CTStyles cTStyles = CTStyles.Factory.parse(cTStyleNormal);
  CTStyle cTStyle = cTStyles.getStyleArray(0);
  styles.addStyle(new XWPFStyle(cTStyle));
  cTStyles = CTStyles.Factory.parse(cTStyleH1XML);
  cTStyle = cTStyles.getStyleArray(0);
  styles.addStyle(new XWPFStyle(cTStyle));
  cTStyles = CTStyles.Factory.parse(cTStyleH2XML);
  cTStyle = cTStyles.getStyleArray(0);
  styles.addStyle(new XWPFStyle(cTStyle));
  cTStyles = CTStyles.Factory.parse(cTStyleH3XML);
  cTStyle = cTStyles.getStyleArray(0);
  styles.addStyle(new XWPFStyle(cTStyle));

  cTStyles = CTStyles.Factory.parse(cTStyleTOC1);
  cTStyle = cTStyles.getStyleArray(0);
  styles.addStyle(new XWPFStyle(cTStyle));
  cTStyles = CTStyles.Factory.parse(cTStyleTOC2);
  cTStyle = cTStyles.getStyleArray(0);
  styles.addStyle(new XWPFStyle(cTStyle));

  createParagraphs(document, numID, "First Level@@Second Level@@First Level@@Second Level@@Third Level@@Second Level@@Third Level@@Second Level@@First Level");

  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run=paragraph.createRun();
  run.setText("Table of contents:");

  paragraph = document.createParagraph();

  //document.createTOC();

  CTSimpleField toc = paragraph.getCTP().addNewFldSimple();
  toc.setInstr("TOC \\* MERGEFORMAT");
  toc.setDirty(STOnOff.TRUE);

  FileOutputStream out = new FileOutputStream("CreateWordNumberedHeadings.docx");   
  document.write(out);

 }

 public static void createParagraphs(XWPFDocument doc, BigInteger numID, String content) {
  for (String value : content.split("@@")) {
   XWPFParagraph para = doc.createParagraph();
   para.setVerticalAlignment(TextAlignment.CENTER);
   para.setNumID(numID);
   para.setStyle("Heading1");
   if (value.contains("Second")) {
    para.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
    para.setStyle("Heading2");
   }
   if(value.contains("Third")) {
    para.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(2));
    para.setStyle("Heading3");
   }
   XWPFRun run = para.createRun();
   run.setText(value);
   para = doc.createParagraph();
   run = para.createRun();
   run.setText("Lorem ipsum semit dolor ...");
   run.addBreak(BreakType.PAGE); 
  } 
 }
}

注意:出于上述原因,我不使用XWPFDocument.createTOC()。相反,我插入的字段必须在Word中打开文档时刷新。这会导致打开时出现确认对话框,必须使用Yes来回答。

答案 1 :(得分:0)

您的许多问题似乎与XWPF有关。这是一个不完整的API。您可以阅读规范以确定如何处理API中未显示的内容,然后可能将其捐赠回社区。规格为here。 Apache POI项目使用第一版架构。我发现第1,3和4部分是最有用的。

关于这个具体问题,您是否通过doc.createTOC()得到了您想要的内容?你得到了什么?它位于文档中的适当位置吗?关于TOC还有其他问题。 This one特别有用。如果您需要其他行为,上面提到的规范包含更多TOC字段的开关,例如要包含的自定义标题样式。可以通过修改x为TOC级别的适当TOCx样式来设置TOC级别的样式。