我正在使用Apache POI XWPF组件和java,将.xml文件中的数据提取到word文档中。到目前为止这么好,但我正在努力创建一个目录。我必须在方法的开头创建一个目录,然后在最后更新它以获取所有新标头。目前我使用doc.createTOC(),其中doc是从XWPFDocument创建的变量,在开始时创建表,然后我使用doc.enforceUpdateFields()来更新文档末尾的所有内容。但是当我运行程序后打开文档时,目录是空的,但导航面板确实包含了我指定的一些标题。
评论建议我添加一些代码。所以我开始从模板创建文档:
XWPFDocument doc = new XWPFDocument(new FileInputStream("D://Template.docx"));
然后我创建了一个目录:
doc.createTOC();
然后在整个方法中我将标题添加到文档中:
XWPFParagraph documentControlHeading = doc.createParagraph();
documentControlHeading.setPageBreak(true);
documentControlHeading.setAlignment(ParagraphAlignment.LEFT);
documentControlHeading.setStyle("Tier1Header");
添加完所有标题后,我想更新文档,以便所有新标题都出现在目录中。我这样做是使用以下命令购买的:
doc.enforceUpdateFields();
答案 0 :(得分:0)
嗯...我正在查看import java.util.*;
class calc {
public static void main(String ar[]) {
char choice;
Scanner in = new Scanner(System.in);
System.out.println("WELCOME TO SHREYDAN'S CALC 1.0");
System.out.println(" ");
boolean loop = true;
while (loop) {
System.out.println("YOU CAN DO THE FOLLOWING:");
System.out.println("+: ADDITION");
System.out.println("-: SUBTRACTION");
System.out.println("*: PRODUCT");
System.out.println("/: QUOTIENT");
System.out.println("#: SQUARE ROOT");
System.out.println("^: POWER");
System.out.println("$: ROUND OFF");
System.out.println("!: FACTORIAL");
System.out.println(" ");
System.out.println("ENTER CHOICE");
choice = in.next().charAt(0);
switch (choice) {
case '+':
System.out.println("ENTER 2 NUMBERS, USER");
double a = in.nextDouble();
double b = in.nextDouble();
System.out.println("SUM = " + (a + b));
break;
case '-':
System.out.println("ENTER 2 NUMBERS, USER");
double c = in.nextDouble();
double d = in.nextDouble();
System.out.println("SUBTRACTING " + d + " FROM " + c + " ... DIFFERENCE = " + (c - d));
break;
case '*':
System.out.println("ENTER 2 NUMBERS, USER");
double e = in.nextDouble();
double f = in.nextDouble();
System.out.println("PRODUCT = " + (e * f));
break;
case '/':
System.out.println("ENTER 2 NUMBERS, USER");
double g = in.nextDouble();
double h = in.nextDouble();
System.out.println("DIVIDING " + g + " BY " + h + " = " + (g / h));
break;
case '#':
System.out.println("ENTER NO. FOR SQAURE ROOT:");
double sqrt = in.nextDouble();
System.out.println("SQUARE ROOT OF " + sqrt + " = " + Math.sqrt(sqrt));
break;
case '^':
System.out.println("ENTER BASE, USER");
double base = in.nextDouble();
System.out.println("ENTER POWER, USER");
double power = in.nextDouble();
System.out.println(base + " RAISED TO POWER " + power + " = " + Math.pow(base, power));
break;
case '$':
System.out.println("ENTER DECIMAL VALUES TO ROUND OFF");
double deci = in.nextDouble();
System.out.println("THE NEAREST ROUND OFF = " + Math.round(deci));
break;
case '!':
System.out.println("ENTER A NO. FOR FACTORIAL:");
int fact = in.nextInt();
int factorial = 1;
for (int i = fact; i >= 1; i--)
factorial = factorial * i;
System.out.println(fact + "! = " + factorial);
break;
default:
System.out.println("WRONG CHOICE USER");
}
System.out.println("Want to calculate more?Y/N");
loop = in.next().charAt(0) == 'Y';
}
}
}
方法代码,看起来它看起来像createTOC()
的样式。所以找不到Heading #
。首先尝试创建文本,然后使用Tier1Header
等样式作为标题。然后使用Heading 1
添加TOC。它应该在创建TOC时找到所有标题。我不知道createTOC()
是否会影响TOC。
答案 1 :(得分:0)
//您的docx模板应该包含以下或类似的文本//将被搜索并替换为WORD TOC。
// $ {TOC}
public static void main(String[] args) throws IOException, OpenXML4JException {
XWPFDocument docTemplate = null;
try {
File file = new File(PATH_TO_FILE); //"C:\\Reports\\Template.docx";
FileInputStream fis = new FileInputStream(file);
docTemplate = new XWPFDocument(fis);
generateTOC(docTemplate);
saveDocument(docTemplate);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (docTemplate != null) {
docTemplate.close();
}
}
}
private static void saveDocument(XWPFDocument docTemplate) throws FileNotFoundException, IOException {
FileOutputStream outputFile = null;
try {
outputFile = new FileOutputStream(OUTFILENAME);
docTemplate.write(outputFile);
} finally {
if (outputFile != null) {
outputFile.close();
}
}
}
public static void generateTOC(XWPFDocument document) throws InvalidFormatException, FileNotFoundException, IOException {
String findText = "${TOC}";
String replaceText = "";
for (XWPFParagraph p : document.getParagraphs()) {
for (XWPFRun r : p.getRuns()) {
int pos = r.getTextPosition();
String text = r.getText(pos);
if (text != null && text.contains(findText)) {
text = text.replace(findText, replaceText);
r.setText(text, 0);
addField(p, "TOC \\o \"1-3\" \\h \\z \\u");
break;
}
}
}
}
private static void addField(XWPFParagraph paragraph, String fieldName) {
CTSimpleField ctSimpleField = paragraph.getCTP().addNewFldSimple();
// ctSimpleField.setInstr(fieldName + " \\* MERGEFORMAT ");
ctSimpleField.setInstr(fieldName);
ctSimpleField.addNewR().addNewT().setStringValue("<<fieldName>>");
}
答案 2 :(得分:0)
这是createTOC()
的代码,通过检查XWPFDocument.class
:
public void createTOC() {
CTSdtBlock block = getDocument().getBody().addNewSdt();
TOC toc = new TOC(block);
for (XWPFParagraph par : this.paragraphs) {
String parStyle = par.getStyle();
if ((parStyle != null) && (parStyle.startsWith("Heading"))) try {
int level = Integer.valueOf(parStyle.substring("Heading".length())).intValue();
toc.addRow(level, par.getText(), 1, "112723803");
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
正如您所看到的,它将TOC的所有段落添加到名为&#34; HeadingX
&#34;的样式中,其中X为数字。但不幸的是,这还不够。事实上,该方法在其实现中存在错误/不完整。
传递给addRow()
的网页代码始终为1
,甚至没有计算。
因此,最后,您将拥有一个包含所有段落的TOC,并且尾随点会给出正确的缩进,但页面将始终等于&#34; 1&#34;。
修改强> ......但是,有一个解决方案here。