Apache POI 3.10 Final XWPFDocument.setParagraph()
Я просматриваю документы 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>
Все это, как говорится, я НЕ удалил оригинальные.jars, упакованные с CF. Я недавно попытался и не смог, я уверен, что смогу, если я, конечно, постараюсь немного сильнее, но чувствую, что в этом нет необходимости.
Я делаю вызов CreateObject для создания экземпляра java.io.File и java.io.FileOutputStream. Это как-то возвращает экземпляр моего XWPFDocument к классу CF по умолчанию?
1 ответ
это происходит из-за обновления Apache POI .jars и больше не поддерживает метод setParagraph()
Можете ли вы уточнить "не удалось получить доступ"? Что такое точное исключение и трассировка стека?
Скорее всего, наоборот. Вместо того, чтобы быть устаревшим или удаленным, этот метод был фактически добавлен в более новой версии, чем та, которую вы используете. Как упомянул @Gagravarr, CF поставляется со старой версией POI. Вы не сообщили нам свою версию CF, но CF10 в комплекте с POI "3.6-beta1". Live API обычно указывает на последнюю стабильную версию, в настоящее время "3.10 Final". Очевидно, что 3.10 может включать новые методы и / или классы, которые не будут доступны при использовании более ранних версий.
Существует несколько вариантов использования более новой версии POI.
- Перезаписать существующие файлы POI в
{cf_root}\lib
с более новыми версиями. Затем перезапустите сервер CF (обязательно). Примечание: я не делал это лично, поэтому я не знаю, нарушит ли это другие функции - Для CF9 или более ранней версии используйте JavaLoader.cfc для параллельного запуска более новой версии.
- Начиная с CF10, в JavaLoader.cfc есть выпечка. Так что вы можете использовать
this.javaSettings
в вашем Application.cfc для загрузки более новых версий файлов POI.
Заметьте, что Word API не так совершенен, как для 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:
Интересно. Код загружает старую версию, но не по вышеуказанной причине. (См. Совет по отладке: определение, из какого Jar-файла был загружен класс в ColdFusion MX)
Я считаю, что причиной проблемы является то, что параметр paths JavaLoder написан с ошибкой: loatPaths
вместо loadPaths
, По умолчанию это пустой массив. В результате вы не загружаете новые банки. поскольку loadColdFusionClassPath=true
вместо этого вы загружаете старую версию.
Примечание: более простой способ создать список путей в CF9 - это использовать DirectoryList()
, Эта функция позволит вам захватить все пути за один выстрел. Тем не менее, одно очень важное замечание. POI использует библиотеку dom4j, которая известна проблемами загрузки классов. Загрузка двух версий фляги вызовет проблемы - даже с JavaLoader. Поэтому обязательно удалите /poi/ooxml-lib/dom4j-1.6.1.jar
файл первым. (Это также должно устранить необходимость поменять currentClassloader
).
jarPaths = DirectoryList(expandPath("/poi/"), true, "path", "*.jar")