Apache POI 3.10 Final XWPFDocument.setParagraph()

时间:2014-08-14 06:12:56

标签: java apache coldfusion apache-poi coldfusion-9

我正在查看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的默认类?

1 个答案:

答案 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服务器(必需)。 注意:我个人没有这样做,所以我不知道这样做是否会破坏其他功能
  • 对于CF9或更早版本,请使用JavaLoader.cfc并行运行较新版本。
  • 从CF10开始,存在一个JavaLoader.cfc的内容。所以你可以在Application.cfc中使用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")