问题
I need to do docx manipulation (find/replace on placeholders and checking/unchecking checkboxes). Since ColdFusion 10 integrates well with Java, I decided to try and use the Java library docx4j, which basically mimics the OpenXML SDK (.net platform).
I have the docx4j JAR inside a custom folder, which I have setup in my Application.cfc via JavaSettings (new in CF10, and I tried it with other JARS and it works):
<cfcomponent output="false">
<cfset this.javaSettings =
{LoadPaths = ["/myJava/lib"], loadColdFusionClassPath = true, reloadOnChange= true,
watchInterval = 100, watchExtensions = "jar,class,xml"} />
</cfcomponent>
Now, I'm trying to use this sample:https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/samples/VariableReplace.java
But trying to call the WordprocessingMLPackage fails with the function CreateObject() saying that particular class doesn't exist:
<cfset docObj = createObject("java","org.docx4j.openpackaging.packages.WordprocessingMLPackage") />
Any ideas? I'm not really a Java guy, but there are not many options out there for docx manipulation.
回答1:
Alright. Seems like I got everything working. I just got to figure out how to do a find/replace, and everything else I want to do in a docx document. Here's my code so far to show you guys that it looks like it is working (make sure that your Application.cfc looks like the original post if you are on CF10):
<cfscript>
docPackageObj = createObject("java","org.docx4j.openpackaging.packages.WordprocessingMLPackage").init();
docObj = createObject("java","org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart").init();
xmlUtilObj = createObject("java","org.docx4j.XmlUtils").init();
wmlDocObj = createObject("java","org.docx4j.wml.Document").init();
saveToZipFile = createObject("java","org.docx4j.openpackaging.io.SaveToZipFile").init(docPackageObj);
strFilePath = getDirectoryFromPath(getCurrentTemplatePath()) & "testDoc.docx";
wordMLPackage =
docPackageObj.load(createObject("java","java.io.File").init(javaCast("string",strFilePath)));
documentPart = wordMLPackage.getMainDocumentPart();
// unmarshallFromTemplate requires string input
strXml = xmlUtilObj.marshaltoString(documentPart.getJaxbElement(),true);
writeDump(var="#strXml#");
</cfscript>
Now, does anybody know how to cast structures in ColdFusion into hashmaps (or collections in general)? I think structures in CF are actually util.Vector, whereas hashmaps are util.HashMap. All of the examples I see with Docx4j that demonstrates find/replace in placeholders use this:
HashMap<String, String> mappings = new HashMap<String, String>();
mappings.put("colour", "green");
mappings.put("icecream", "chocolate");
回答2:
Have you tried setting loadColdFusionClassPath = false instead of true? Perhaps there is a conflict with some of the JARs that ship w/ CF.
回答3:
(Not really a new answer, but it is too much code for comments ..)
Here is the full code for the docx4j VariableReplace.java example
<cfscript>
saveToDisk = true;
inputFilePath = ExpandPath("./docx4j/sample-docs/word/unmarshallFromTemplateExample.docx");
outputFilePath = ExpandPath("./OUT_VariableReplace.docx");
inputFile = createObject("java", "java.io.File").init(inputFilePath);
wordMLPackage = createObject("java","org.docx4j.openpackaging.packages.WordprocessingMLPackage").load(inputFile);
documentPart = wordMLPackage.getMainDocumentPart();
XmlUtils = createObject("java","org.docx4j.XmlUtils");
xmlString = XmlUtils.marshaltoString(documentPart.getJaxbElement(),true);
mappings = createObject("java", "java.util.HashMap").init();
mappings["colour"] = "green";
mappings["icecream"] = "chocolate";
obj = XmlUtils.unmarshallFromTemplate(xmlString , mappings);
documentPart.setJaxbElement(obj);
if (saveToDisk) {
saveToZipFile = createObject("java","org.docx4j.openpackaging.io.SaveToZipFile").init(wordMLPackage);
SaveToZipFile.save( outputFilePath );
}
else {
WriteDump(XmlUtils.marshaltoString(documentPart.getJaxbElement(), true, true));
}
</cfscript>
来源:https://stackoverflow.com/questions/10825539/coldfusion-java-docx4j-library