gpt4 book ai didi

java - 使用 docx4j 从 .dotx 模板生成 .docx 文档(在 XPages 应用程序中)

转载 作者:行者123 更新时间:2023-11-29 03:18:47 28 4
gpt4 key购买 nike

我在 XPages 应用程序中使用 docx4j 创建包含 XPage 内容的 Word 文档。 Word 文档(.docx 格式)是基于模板(也是 docx.format)创建的。这一切都很好。但是,当我将模板从.docx 格式更改为.dotx 格式时,无法打开生成的Word 文档(.docx)。在尝试打开文档时,我收到一条错误消息,指出内容导致问题。

谁能告诉我如何使用 docx4j 将 .dotx 文件转换为 .docx 文件?

我目前使用的代码是:

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;

import org.docx4j.XmlUtils;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.ContentAccessor;

import org.slf4j.impl.*;

import java.io.FileInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.docx4j.wml.*;

import org.apache.commons.lang3.StringUtils;

import java.util.Enumeration;
import java.util.Map;
import java.util.Iterator;
import java.util.Vector;

import lotus.domino.Document;
import lotus.domino.*;

import org.docx4j.openpackaging.parts.WordprocessingML.DocumentSettingsPart;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.openpackaging.parts.relationships.Namespaces;

public class JavaTemplateDocument {


public void mainCode(Session session, Document currDoc, String empLang, String templateType, String sArt) throws Exception {

Database dbCurr = session.getCurrentDatabase();
String viewName = "vieTemplateLookup";
View tview = dbCurr.getView(viewName);
Vector viewKey = new Vector();
viewKey.addElement(empLang);
viewKey.addElement(templateType);
Document templateDoc = tview.getDocumentByKey(viewKey);
if (tview.getDocumentByKey(viewKey) == null ) System.out.println("templateDoc is NULL");

Item itmNotesFields = templateDoc.getFirstItem("NotesFieldList");
Item itmWordFields = templateDoc.getFirstItem("WordFieldList");

Vector<String[]> notesFields = itmNotesFields.getValues();
Vector<String[]> wordFields = itmWordFields.getValues();

int z = notesFields.size();
int x = wordFields.size();

Enumeration e1 = notesFields.elements();

Enumeration e2 = wordFields.elements();

WordprocessingMLPackage template = getTemplate("C:\\Temp\\AZG Sample Template.dotx","C:\\Temp\\AZG Sample Template.docx");

for (int y = 0; y < x; y++) {
if (currDoc.hasItem(String.valueOf(notesFields.elementAt(y)))) {
Item itmNotesName = currDoc.getFirstItem(String.valueOf(notesFields.elementAt(y)));
replacePlaceholder(template, itmNotesName.getText(), String.valueOf(wordFields.elementAt(y))); }
else {
replacePlaceholder(template, "", String.valueOf(wordFields.elementAt(y)));
}
}

writeDocxToStream(template, "C:\\Temp\\AZG Sample Document.docx");
createResponseDocument(dbCurr, currDoc, templateDoc, sArt);
}

private void createResponseDocument(Database dbCurr, Document currDoc, Document templateDoc, String sArt) throws NotesException{

Document respDoc = dbCurr.createDocument(); // create the response document
String refVal = currDoc.getUniversalID();

respDoc.appendItemValue("IsDocTemplate", "1");
if (currDoc.hasItem("Name")) {
respDoc.appendItemValue("Name", currDoc.getItemValue("Name"));}
else {System.out.println("Name is not available"); }
if (currDoc.hasItem("Firstname")) {
respDoc.appendItemValue("Firstname", currDoc.getItemValue("Firstname"));}
else {System.out.println("Firstname is not available"); }
if (currDoc.hasItem("ReferenceTypeTexts")) {
respDoc.appendItemValue("ReferenceTypeTexts", currDoc.getItemValue("ReferenceTypeTexts"));}
else {System.out.println("ReferenceTypeTexts is not available"); }
if (currDoc.hasItem("ReferenceType")) {
respDoc.appendItemValue("ReferenceType", currDoc.getItemValue("ReferenceType"));}
else {System.out.println("ReferenceType is not available"); }
System.out.println("Append Form value");
respDoc.appendItemValue("Form", "frmRespTempl");


respDoc.makeResponse(currDoc);
RichTextItem body = respDoc.createRichTextItem("Body");
body.embedObject(1454, "", "C:\\Temp\\AZG Sample Document.docx", null);
respDoc.save();
}


/*
* Create a simple word document that we can use as a template.
* For this just open Word, create a new document and save it as template.docx.
* This is the word template we'll use to add content to.
* The first thing we need to do is load this document with docx4j.
*/

private WordprocessingMLPackage getTemplate(String source, String target) throws Docx4JException, FileNotFoundException, IOException {

String WORDPROCESSINGML_DOCUMENT = "application/vnd.openxmlformats- officedocument.wordprocessingml.document.main+xml";
final ContentType contentType = new ContentType(WORDPROCESSINGML_DOCUMENT);

String templatePath = source;

File sourceFile = new File(source);
File targetFile = new File(target);
copyFileUsingFileChannels(sourceFile, targetFile);

WordprocessingMLPackage template = WordprocessingMLPackage.load(new FileInputStream(targetFile));

ContentTypeManager ctm = wordMLPackage.getContentTypeManager();
ctm.addOverrideContentType(new URI("/word/document.xml"),WORDPROCESSINGML_DOCUMENT);

DocumentSettingsPart dsp = new DocumentSettingsPart();
CTSettings settings = Context.getWmlObjectFactory().createCTSettings();
dsp.setJaxbElement(settings);
wordMLPackage.getMainDocumentPart().addTargetPart(dsp);

// Create external rel
RelationshipsPart rp = RelationshipsPart.createRelationshipsPartForPart(dsp);
org.docx4j.relationships.Relationship rel = new org.docx4j.relationships.ObjectFactory().createRelationship();
rel.setType( Namespaces.ATTACHED_TEMPLATE );
rel.setTarget(templatePath);
rel.setTargetMode("External");
rp.addRelationship(rel); // addRelationship sets the rel's @Id

settings.setAttachedTemplate(
(CTRel)XmlUtils.unmarshalString("<w:attachedTemplate xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\"" + rel.getId() + "\"/>", Context.jc, CTRel.class)
);

return template;
}

private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
List<Object> result = new ArrayList<Object>();
if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();

if (obj.getClass().equals(toSearch))
result.add(obj);
else if (obj instanceof ContentAccessor) {
List<?> children = ((ContentAccessor) obj).getContent();
for (Object child : children) {
result.addAll(getAllElementFromObject(child, toSearch));
}

}
return result;
}

/*
* This will look for all the Text elements in the document, and those that match are replaced with the value we specify.
*/

private void replacePlaceholder(WordprocessingMLPackage template, String name, String placeholder ) {
List<Object> texts = getAllElementFromObject(template.getMainDocumentPart(), Text.class);

for (Object text : texts) {
Text textElement = (Text) text;
if (textElement.getValue().equals(placeholder)) {
textElement.setValue(name);
}
}
}

/*
* write the document back to a file
*/

private void writeDocxToStream(WordprocessingMLPackage template, String target) throws IOException, Docx4JException {
File f = new File(target);
template.save(f);
}

/*
* Example code for replaceParagraph
*
String placeholder = "SJ_EX1";
String toAdd = "jos\ndirksen";

replaceParagraph(placeholder, toAdd, template, template.getMainDocumentPart());
*/

private void replaceParagraph(String placeholder, String textToAdd, WordprocessingMLPackage template, ContentAccessor addTo) {
// 1. get the paragraph
List<Object> paragraphs = getAllElementFromObject(template.getMainDocumentPart(), P.class);

P toReplace = null;
for (Object p : paragraphs) {
List<Object> texts = getAllElementFromObject(p, Text.class);
for (Object t : texts) {
Text content = (Text) t;
if (content.getValue().equals(placeholder)) {
toReplace = (P) p;
break;
}
}
}

// we now have the paragraph that contains our placeholder: toReplace
// 2. split into seperate lines
String as[] = StringUtils.splitPreserveAllTokens(textToAdd, '\n');

for (int i = 0; i < as.length; i++) {
String ptext = as[i];

// 3. copy the found paragraph to keep styling correct
P copy = (P) XmlUtils.deepCopy(toReplace);

// replace the text elements from the copy
List<?> texts = getAllElementFromObject(copy, Text.class);
if (texts.size() > 0) {
Text textToReplace = (Text) texts.get(0);
textToReplace.setValue(ptext);
}

// add the paragraph to the document
addTo.getContent().add(copy);
}

// 4. remove the original one
((ContentAccessor)toReplace.getParent()).getContent().remove(toReplace);

}

/*
* A set of hashmaps that contain the name of the placeholder to replace and the value to replace it with.
*
* Map<String,String> repl1 = new HashMap<String, String>();
repl1.put("SJ_FUNCTION", "function1");
repl1.put("SJ_DESC", "desc1");
repl1.put("SJ_PERIOD", "period1");

Map<String,String> repl2 = new HashMap<String, String>();
repl2.put("SJ_FUNCTION", "function2");
repl2.put("SJ_DESC", "desc2");
repl2.put("SJ_PERIOD", "period2");

Map<String,String> repl3 = new HashMap<String, String>();
repl3.put("SJ_FUNCTION", "function3");
repl3.put("SJ_DESC", "desc3");
repl3.put("SJ_PERIOD", "period3");

replaceTable(new String[]{"SJ_FUNCTION","SJ_DESC","SJ_PERIOD"}, Arrays.asList(repl1,repl2,repl3), template);
*/

private void replaceTable(String[] placeholders, List<Map<String, String>> textToAdd,
WordprocessingMLPackage template) throws Docx4JException, JAXBException {
List<Object> tables = getAllElementFromObject(template.getMainDocumentPart(), Tbl.class);

// 1. find the table
Tbl tempTable = getTemplateTable(tables, placeholders[0]);
List<Object> rows = getAllElementFromObject(tempTable, Tr.class);

// first row is header, second row is content
if (rows.size() == 2) {
// this is our template row
Tr templateRow = (Tr) rows.get(1);

for (Map<String, String> replacements : textToAdd) {
// 2 and 3 are done in this method
addRowToTable(tempTable, templateRow, replacements);
}

// 4. remove the template row
tempTable.getContent().remove(templateRow);
}
}

private Tbl getTemplateTable(List<Object> tables, String templateKey) throws Docx4JException, JAXBException {
for (Iterator<Object> iterator = tables.iterator(); iterator.hasNext();) {
Object tbl = iterator.next();
List<?> textElements = getAllElementFromObject(tbl, Text.class);
for (Object text : textElements) {
Text textElement = (Text) text;
if (textElement.getValue() != null && textElement.getValue().equals(templateKey))
return (Tbl) tbl;
}
}
return null;
}

private static void addRowToTable(Tbl reviewtable, Tr templateRow, Map<String, String> replacements) {
Tr workingRow = (Tr) XmlUtils.deepCopy(templateRow);
List<?> textElements = getAllElementFromObject(workingRow, Text.class);
for (Object object : textElements) {
Text text = (Text) object;
String replacementValue = (String) replacements.get(text.getValue());
if (replacementValue != null)
text.setValue(replacementValue);
}

reviewtable.getContent().add(workingRow);
}

private static void copyFileUsingFileChannels(File source, File dest)
throws IOException {
FileChannel inputChannel = null;
FileChannel outputChannel = null;
try {
inputChannel = new FileInputStream(source).getChannel();
outputChannel = new FileOutputStream(dest).getChannel();
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
} finally {
inputChannel.close();
outputChannel.close();
}
}

}

最佳答案

从广义上讲,模板 (.dotx) 和文档 (.docx) 之间存在一些差异。这意味着您需要做一些事情——这不仅仅是更改文件扩展名那么简单,无论您是将文档保存为作为模板,还是尝试创建文档< strong>来自模板。

希望这个大纲对您有所帮助:

  1. 首先做您已经做过的事情:您的新文档应该是模板的文件副本
  2. 根据需要更改新的 WordprocessingMLPackage 文档类型(请参阅 ContentTypes 类中的 WORDPROCESSINGML_TEMPLATE)
  3. 创建附加模板并将其附加到您的文档:参见 sample code on Github有关更多详细信息(TemplateAttach.java 示例)。

祝你好运!

关于java - 使用 docx4j 从 .dotx 模板生成 .docx 文档(在 XPages 应用程序中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24907155/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com