我正在查看Apache POI文档,包括我下载的文档和实时网站上的文档。 setParagraph()
类中应该有org.apache.poi.xwpf.usermodel.XWPFDocument
方法。我在ColdFusion中使用此类,并且无法访问文档中列出的许多方法。
这是因为不正确地使用类或可能的类依赖性?或者这是由于Apache POI .jars正在更新而不再支持setParagraph()
方法?
更新
我正在使用ColdFusion 9并使用JavaLoader.cfc加载类。这是我用来实例化操作所需的类的代码。
<cfset javaLoader = server[application.myJavaLoaderKey]>
<cfset OPCPackage = javaLoader.create("org.apache.poi.openxml4j.opc.OPCPackage")>
<cfset dot_template_opc = OPCPackage.open("pathToDocxFileInstantiated")>
<cfset XWPFDocument = javaLoader.create("org.apache.poi.xwpf.usermodel.XWPFDocument")>
<cfset dot_template = XWPFDocument.init(dot_template_opc)>
<cfset XWPFParagraph = javaLoader.create("org.apache.poi.xwpf.usermodel.XWPFParagraph")>
<cfset XWPFTable = javaLoader.create("org.apache.poi.xwpf.usermodel.XWPFTable")>
<cfset XWPFRun = javaLoader.create("org.apache.poi.xwpf.usermodel.XWPFRun")>
<cfset CTP = javaLoader.create("org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP")>
<cfset CTRImpl = javaLoader.create("org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTRImpl")>
<cfset CTText = javaLoader.create("org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText")>
<cfset dot_output = "pathToNewDocxFile"><!--- Edited version of original --->
<cfset outputObject_dot = CreateObject("java","java.io.FiltOutputStream",
"java",
"java.io.FileOutputStream"
).Init(
CreateObject(
"java",
"java.io.File"
).Init(
dot_output
)>
以下是Application.cfc中与JavaLoader.cfc相关的相关代码。它保存在onApplicationStart()方法中。
<cfset var myJavaLoaderKey = "ABCDEF-01234567-9876543210-ABCDEF54321_javaloader">
<cfset var jarPaths = arrayNew(1)>
<!--- if the javaLoader was not created yet --->
<cfif NOT structKeyExists(server, myJavaLoaderKey)>
<!--- these are absolute paths to the POI jar files --->
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/poi-3.10-FINAL-20140208.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/poi-examples-3.10-FINAL-20140208.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/poi-excelant-3.10-FINAL-20140208.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/poi-ooxml-3.10-FINAL-20140208.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/poi-ooxml-schemas-3.10-FINAL-20140208.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/poi-scratchpad-3.10-FINAL-20140208.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/lib/commons-codec-1.5.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/lib/commons-logging-1.1.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/lib/junit-4.11.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/lib/log4j-1.2.13.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/ooxml-lib/dom4j-1.6.1.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/ooxml-lib/stax-api-1.0.1.jar")) >
<cfset arrayAppend( jarPaths, expandPath("../wwwroot/poi/ooxml-lib/xmlbeans-2.3.0.jar")) >
<cfif NOT structKeyExists(server, myJavaLoaderKey)>
<cflock name="#Hash(myJavaLoaderKey)#" type="exclusive" timeout="10">
<!--- create an instance of the JavaLoader and store it in the server scope --->
<cfset server[myJavaLoaderKey] = createObject("component", "javaloader.JavaLoader").init(loatPaths=jarPaths,loadColdFusionClassPath=true)>
</cflock>
</cfif>
<cfset application.myJavaLoaderKey = myJavaLoaderKey>
</cfif>
<cfscript>
_Thread = createObject("java", "java.lang.Thread");
currentClassloader = _Thread.currentThread().getContextClassLoader();
try { // Set the current thread's context class loader as Javaloader's classloader, so dom4j doesn't die _Thread.currentThread().setContextClassLoader(server[var.JLKey].getURLClassLoader());
}
catch(Any exc) {
rethrow;
}
finally { // We have to reset the classloader, due to thread pooling.
_Thread.currentThread().setContextClassLoader(currentClassloader);
}
</cfscript>
所有这些都说,我没有删除与CF一起打包的原始.jars。我最近尝试过并且无法做到,我确信如果我当然尝试一点努力,我觉得可以,但是,觉得这不是必要的。
我正在调用CreateObject来实例化java.io.File和java.io.FileOutputStream。这是否以某种方式将我的XWPFDocument的实例化还原为CF的默认类?
答案 0 :(得分:2)
这是由于Apache POI .jars正在更新而不再支持 setParagraph()方法
你能澄清“无法访问”吗?什么是确切的异常和堆栈跟踪?
很可能恰恰相反。该方法实际上是在比您正在使用的版本更新的版本中添加,而不是被弃用或删除。正如@Gagravarr所提到的,CF附带了旧版本的POI。您没有告诉我们您的CF版本,但CF10与POI“3.6-beta1”捆绑在一起。 live API通常指向最新的稳定版本,目前为“3.10 Final”。显然3.10可能包括在使用早期版本时将无法使用的新方法和/或类。
using a newer version of POI有几种选择。
{cf_root}\lib
中的现有POI广告。然后重启CF服务器(必需)。 注意:我个人没有这样做,所以我不知道这样做是否会破坏其他功能 this.javaSettings
来加载更新版本的POI jar。旁注,Word API is not as mature as the one for Excel,请记住这一点。
更新1:
你是如何确定对象“没有setParagraph”方法的?如果您执行了cfdump
,并且没有看到列出的setParagraph()
方法,那么您可能不加载该类的较新版本。您能否发布代码,显示如何实例化JavaLoader并创建
XWPFDocument
对象?
在不知情的情况下,我的猜测可能是你不小心在某处使用了createObject()
。因此,您仍然可以使用较旧版本的课程,而不是较新版本的课程。即:
//this loads the older version in cf_root/lib
createObject("java", "path.to.Class");
// this loads the newer version in JavaLoader paths
javaLoader.create("path.to.Class");
更新2:
有趣。代码 加载旧版本,但不是出于上述原因。 (见Debugging Tip: Identifying Which Jar file a class was loaded from in ColdFusion MX)
我认为问题的原因是JavaLoder路径参数拼写错误:loatPaths
而不是loadPaths
。所以它默认为空数组。结果是你实际上没有加载任何的新罐子。自loadColdFusionClassPath=true
以来,您最终会加载旧版本。
旁注,一种在CF9中生成路径列表的简单方法是使用DirectoryList()
。该功能允许您一次性获取所有路径。那说,一个非常重要的说明。 POI使用dom4j库,它以类加载问题而闻名。加载两个版本的jar会导致问题 - 即使使用JavaLoader也是如此。因此,请务必先删除/poi/ooxml-lib/dom4j-1.6.1.jar
文件。 (这也应该不需要换掉currentClassloader
)。
jarPaths = DirectoryList(expandPath("/poi/"), true, "path", "*.jar")