Конвертация и "офисные" форматы

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 583
269
#1
долгое время не мог найти "нормального" инструмента (ОЛЕ не предлагать :) )...
НО вышел POI 3.8 beta4
он примечателен готовыми конверторами:
Word-to-HTML Converter, конвертирующий документ Word в HTML, можно даже с картинками;
Word-to-Text Converter, который является заменой для прошлого WordExtractor, корректно обрабатывающий вложенные OLE-документы, разбиение на абзацы, коды полей (в том числе гиперссылки);
Word-to-FO Converter, конвертирующий документ Word в файл XSL FO, также возможно с картинками. Дальше этот файл можно передать на обработку в Apache FOP для получения PDF из Word.
цитата с хабра

По реалиям - всё это лежит в либе poi-scratchpad-3.8-beta4-20110826.jar
и запущаеть можно строкой:
java -cp ./:./poi-3.8-beta4/poi-3.8-beta4-20110826.jar:./poi-3.8-beta4/poi-scratchpad-3.8-beta4-20110826.jar org.apache.poi.hwpf.converter.WordToHtmlConverter <input> <output>
с соответ. именем класса
результат, в хтмл, мне понравился (съехала нумерация булетов, на 1-цу, но не суть) - он визуально аккуратнее, чем при сохранении МСО2000 вордом
и самое "вкусное" - это fop преобразование, из класса org.apache.poi.hwpf.converter.WordToFoConvertor
приятно это тем, что можно получать PDF из вордфайла, без "посредников" (если не считать FOP и POI ;) )
и в процесс можно вмешиваться, подставляя FOP-у шрифты/стили, заменяя элементы

д.р. словами - шаблонизация на основе ворд файлов, но с выводом в ПДФ!

стоит ли говорить, что всё это бохгасьво можно задейстовать в нотусне ;)
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 583
269
#2
теория преобразования и шаблон
стадия подготовки
-в тексте DOC файла, юзвери (ответ. за создание шаблона) создают некие теги (далее назовём их полями, не путать с вордовыми полями), например <FieldName>
-файл в формате DOC подаем на вход обработчику и он его преобразует в формат FO
-получаем из поля из FO, преобразованием XSLT
-заносим поля в БД нотусни
стадия генерации
-юзверь забивает значения полей
-с пом. apache velocity подставляем значения в FO файл (кодом в БД). Например так, там "поля" выгдядят как $name и т.п., мы же можем сделать <name> (это угловые скобки)
-с пом. FOP генерим выходной ПДФ

с чем столкнулся, при генерации (нек. блоки изложенные в теории уже тестил):
-булеты ворда - если их создавали абы-как надо пересоздать (убить нумерацию и сделать заново). А то - может съехать нумерация
-тект суперскриптом обозначен в FO как smaller, но в фоп 0.95 (именно им я обрабатывал) такое значение атрибута не описано. Выход - заменить (можно ХСЛТ, можно велосити) на font-size="6" (или меньше)
-абзацы (fo:block) имеют атрибут http://www.w3schools.com/xslfo/prop_linefeed-treatment.asp как preserv, что приводит к разрыву слов и предложений, если меняется шрифт. Меняем на ignore (методы в предыдущем пункте)
-некоторые "странные" люди форматируют положение текста, на странице - созданием таблиц со строками опред. высоты. Решение - искоренять такой метод форматирования :)
-каментил блок
XML:
<!--<fo:declarations>
<x:xmpmeta xmlns:x="adobe:ns:meta">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="">
<dc:title xmlns:dc="http://purl.org/dc/elements/1.1/"> </dc:title>
<dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/"> </dc:creator>
<dc:description xml:lang="x-default" xmlns:dc="http://purl.org/dc/elements/1.1/"> </dc:description>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
</fo:declarations>-->
ибо в моих версиях эти нэйм-спейсы вызывают вопросы софта
 
Последнее редактирование модератором:
F

FedeX

#3
Добрый день, пытаюсь сделать нечто похожее (надо сформировать картинку с превью вордовского файла). При помощи wordtofo конвертера из состава jpoi получаю fo-файл, затем пытаюсь его обработать apache fop-ом. В итоге внутри transformer.transform(src, res); получаю кучу null-pointer ексцепшенов парсера. Мне кажеться, что сам fo файл зависит от некой теблици стилей (xss или как её там), но если так, то где её взять? Или в чем ещё может быть ошибка?
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 583
269
#4
Мне кажеться, что сам fo файл зависит от некой теблици стилей (xss или как её там), но если так, то где её взять? Или в чем ещё может быть ошибка?
сходу не подскажу, надо видеть FO, выше я описывал траблы, кот. не учтены в 0.95 версии ФОП, более поздней я не прогонял, да и трэйс может подсказать - что не так
 
F

FedeX

#5
Вот к примеру в архиве хтмл с картинкой и получившийся fo-файл (кстати вордвьювером открываеться, но как-то коряво)..
А вот и "ругательства":

Код:
WARNING: Unknown formatting object "{adobe:ns:meta}xmpmeta" encountered (a child of fo:declarations}. (See position 10:2)
ERROR: ''
javax.xml.transform.TransformerException: java.lang.NullPointerException
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)
at com.iq4you.WordPreviewGenerator.tryWithFop(WordPreviewGenerator.java:321)
at com.iq4you.Tests.TestWord(Tests.java:73)
at com.iq4you.Tests.main(Tests.java:101)
Caused by: java.lang.NullPointerException
at org.apache.fop.fo.extensions.xmp.AbstractMetadataElement.notifyObjectBuilt(AbstractMetadataElement.java:65)
at org.apache.fop.fo.extensions.xmp.XMPContentHandlerFactory$FOPXMPHandler.endDocument(XMPContentHandlerFactory.java:65)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:182)
at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndEl
ement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocum
ent(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(Unknown Source)
... 5 more
---------
java.lang.NullPointerException
at org.apache.fop.fo.extensions.xmp.AbstractMetadataElement.notifyObjectBuilt(AbstractMetadataElement.java:65)
at org.apache.fop.fo.extensions.xmp.XMPContentHandlerFactory$FOPXMPHandler.endDocument(XMPContentHandlerFactory.java:65)
at org.apache.fop.fo.FOTreeBuilder.endElement(FOTreeBuilder.java:182)
at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndEl
ement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocum
ent(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)
at com.iq4you.WordPreviewGenerator.tryWithFop(WordPreviewGenerator.java:321)
at com.iq4you.Tests.TestWord(Tests.java:73)
at com.iq4you.Tests.main(Tests.java:101)
 

Вложения

F

FedeX

#7
Ой)) Точно, вот невнимательный я)) Спасибо, теперь работает.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 583
269
#8
очередное исследование...
но оно не касается, напрямую, МСО
речь пойдет об ODF
исследовал вот этот тулз http://simple.odftoolkit.org/cookbook/index.html
интересовала именно работа как с шаблоном, плюсы этой либы - отсутствие необходимости установки приложений для работы с ODF
что обнаружил:
-ищет и заменяет слова ;)
-в нек. комбинациях форматирования глючит
глючало при расположении шаблона для замены в таблице и с нумерацией (см. файл odftest-fail.odt)
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"код"</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='java'>import java.io.InputStream;

import org.odftoolkit.simple.*;
import org.odftoolkit.simple.common.navigation.*;
public class ODFtools {
void replaceText(TextDocument textdoc, String search, String replace) {
TextNavigation searchnav = null;
searchnav = new TextNavigation(search, textdoc);
try{
while (searchnav.hasNext()) {
TextSelection item = (TextSelection) searchnav.nextSelection();
System.out.println("find");
try {
item.replaceWith(replace);
} catch (InvalidNavigationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}catch (Exception e){System.out.println(e.getMessage());}
}
public static void main(String[] argv){
ODFtools obj=new ODFtools();
Class resourceClass = ODFtools.class;
TextDocument textdoc=null;
InputStream is=null;
try {
is=resourceClass.getResourceAsStream("odftest.odt");
// is=resourceClass.getResourceAsStream("odftest-fail.odt");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (is==null){System.out.println ("opening file Error");System.exit(0);}
try {
textdoc=TextDocument.loadDocument(is);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (is==null){System.out.println ("opening document Error");System.exit(0);}
String search="<test>", replace="*replace*";
obj.replaceText(textdoc, search, replace);
System.out.println("exit search");
try {
textdoc.save("new.odt");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}[/CODE]
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"результат когда все нормально"</div></div><div class="sp-body"><div class="sp-content">find
find
find
01.03.2012 14:31:23 org.odftoolkit.simple.style.DefaultStyleHandler getTextPropertiesForRead
INFO: No explicit text properties definition is found!
find
01.03.2012 14:31:23 org.odftoolkit.simple.style.DefaultStyleHandler getTextPropertiesForRead
INFO: No explicit text properties definition is found!
find
exit search
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"результат когда фэйл"</div></div><div class="sp-body"><div class="sp-content">find
find
find
01.03.2012 14:34:37 org.odftoolkit.simple.style.DefaultStyleHandler getTextPropertiesForRead
INFO: No explicit text properties definition is found!
null
exit search
ну и эклипсовый проект (в нем код, файлы исходные и резалт)
Посмотреть вложение ODF.zip
в билдпаз нужно подключить:
- http://repo1.maven.org/maven2/org/odftoolk...-java-0.8.7.jar
- и либы отседова (архив) http://www.poolsaboveground.com/apache//xe...-bin.2.11.0.zip
jvm 1.6+ - что означает применимость начиная с 8.5 домины/нотес
 

Вложения

  • 41 КБ Просмотры: 79

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 583
269
#11
как возможность (XAgent) - замечательно, тока (как всегда) буржую забывают о языках отличных от англицкого ;)
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 583
269
#13
я то думал... :)
а там тока как таблица документ экспортируется (поля в виде таблицы), при создании топика я упирал именно на экпорт форматированного текста