2012-05-30 2 views
2

Мне нужно выполнить манипуляции с docx (найти/заменить на заполнителях и установить/снять флажки). Поскольку ColdFusion 10 хорошо интегрируется с Java, я решил попробовать использовать библиотеку docx4j Java, которая в основном имитирует OpenXML SDK (платформу .net).ColdFusion & Java (библиотека docx4j)

У меня есть docx4j JAR внутри пользовательской папки, которую я имею установку в моем Application.cfc через JavaSettings (новые в CF10, и я попытался его с другими БАНКИ и он работает):

<cfcomponent output="false"> 

    <cfset this.javaSettings = 
     {LoadPaths = ["/myJava/lib"], loadColdFusionClassPath = true, reloadOnChange= true, 
     watchInterval = 100, watchExtensions = "jar,class,xml"} /> 

</cfcomponent> 

сейчас Я пытаюсь использовать этот пример: https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/samples/VariableReplace.java

Но попытка вызвать WordprocessingMLPackage терпит неудачу с функцией CreateObject() о том, что конкретный класс не существует:

<cfset docObj = createObject("java","org.docx4j.openpackaging.packages.WordprocessingMLPackage") /> 

Любые идеи? Я не являюсь Java-парнем, но там не так много вариантов для манипуляций с docx.

+0

Класс не существует ... хммм..поэтому он не был найден. Вы уверены, что файл jar находится там, где он должен быть? Используется java с Coldfusion 7, но похоже, что они сейчас играют хорошо. – Andreas

+0

Опубликовать полную трассировку стека. Тем не менее, я скажу, что я пытался использовать docxj с CF9 некоторое время назад и не мог заставить его работать. Это ничего против docx4j. Казалось, это довольно хорошая библиотека. Я просто столкнулся с слишком большим количеством конфликтов загрузчика классов между зависимостями docx4j и внутренними библиотеками CF. К сожалению, я не смог понять, как их разрешить - даже с JavaLoader. Я не пробовал это с CF10, хотя, поэтому YMMV. – Leigh

+0

С помощью нового свойства JavaSettings в CF10 у меня не было проблем с загрузкой любых других файлов JAR и доступа к классам. Я подумал, что это был именно этот класс, поэтому я попробовал другой класс, чтобы создать объект из (org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart), и он работал отлично. Я буду продолжать обманывать, пытаясь понять, смогу ли я создать/манипулировать документом. Edit: Хорошо, теперь он работает, я думаю, проблема была в том, что я не поставлял конструктор _init() _. –

ответ

0

Вы пробовали установить loadColdFusionClassPath = false вместо true? Возможно, есть конфликт с некоторыми из JAR, которые отправляют w/CF.

1

Хорошо. Похоже, у меня все работает. Мне просто нужно выяснить, как сделать поиск/замену, и все остальное, что я хочу сделать в документе docx. Вот мой код так далеко, чтобы показать вам, ребята, что это выглядит, как он работает (убедитесь, что ваш Application.cfc похож на оригинальный пост, если вы на 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> 

Теперь, знает кто-нибудь, как литые структуры в ColdFusion в хэшмапы (или коллекции вообще)? Я думаю, что структуры в CF фактически используются. Vector, тогда как hashmaps используются. HashMap. Все примеры, которые я вижу с docx4j, который демонстрирует найти/заменить в заполнители использовать этот:

HashMap<String, String> mappings = new HashMap<String, String>(); 
mappings.put("colour", "green"); 
mappings.put("icecream", "chocolate"); 
+0

Очень приятно, я не могу дождаться, чтобы попробовать. Что касается типов данных, то структуры CF являются объектами 'java.util.Map' и массивами' java.util.Vector'. Поэтому я предполагаю, что структура будет работать.Подробнее см. [Преобразования типов данных] (http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24-7884.html) ** Редактирование **: быстрый вопрос, в какой версии docx4j вы используете и что у вас? – Leigh

+0

Кроме того, вы делали что-нибудь особенное с баночками или просто загружали все, т.е. все зависимости? – Leigh

+0

Хорошо спасибо. С другой стороны, вы, возможно, не сможете использовать структуру CF. Похоже, что эта библиотека закодирована для реализации (HashMap) вместо интерфейса (Карта) ... тьфу. Я ненавижу, когда они это делают. – Leigh

0

(на самом деле не новый ответ, но это слишком много кода для комментариев ..)

Вот полный код для docx4j VariableReplace.java пример

<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> 
+0

Похоже, он работает, вам просто нужно настроить HashMap, поскольку точечная нотация не будет работать. Вместо этого это происходит (я просто передал в строковых переменных): _mappings.put ("color", # trim (variables.myColour) #); _ _mappings.put ("icecream", # trim (variables.myIcecream) #) ; _ . Одна вещь, которую я заметил, заключается в том, что если вы измените документ (оригинал с заполнителями) вообще, это приведет к тому, что заполнитель будет распространен на несколько элементов w: t, что приведет к его неработоспособности. Я предполагаю, что нам придется использовать какой-то тип выражения XPath? Я сейчас просматриваю образцы для решения. –

+0

Извините, мой плохой. Было уже поздно и вклеена неправильная версия. Предполагалось, что это скобки. (Обновлено). Я не уверен в элементах. Мне нужно было поближе посмотреть, что происходит. – Leigh

+0

Да, похоже, что они могут быть w: r, w: t и w: rPr элементами внутри одного заполнителя, если вы редактируете документ и меняете вещи и т. Д. Поэтому я пытаюсь выяснить способ, которым заполнитель может быть найден/заменен независимо от того, распространен ли он среди множества элементов, которые Word может подбросить в него. :/ –

Смежные вопросы