for flooders
:: Главная :: Решения :: Статьи :: Сайт М. Дроздова :: Файловый архив :: Книга по VFP 9 :: Русский Help Online :: OFF-LINE Форум
   Лисоводы   всех   стран,  объединяйтесь !!!  

Список Форумов  :: Обсуждаем проекты
  

Генерация отчета в ODT-файл (альтернатива docx)+конвертация отчетов в другие форматы
maple4
Автор

Сообщений: 210
Откуда: Москва
Дата: 22.09.10 13:35:08
1. ГЕНЕРАЦИЯ ОТЧЕТА НА ОСНОВЕ БЛАНКА ODT, пример бланка - файл test_lists_odt.odt
2. Правильный вывод многострочного текста в ODS и ODT-отчетах.
3. Конвертирование полученного отчета в другие форматы с помощью Open Office и jodconverter

Реализовано в рамках одного проекта - формирование отчетов на основе бланков Open Office и Microsoft Office

Почему ODT, а не DOCX?
Во первых, я разобрался с ODS , а разница между ODT и ODS форматами НЕВЕЛИКА.
Во вторых - я не разобрался с XLSX :-( , основным конкурентом ODS (ну, это я так думаю).

Для запуска примера кликните m4rg.exe (или start.prg из FoxPro), программа выведет форму для выбора бланка ( ODS, XML или ODT), после чего сформированный отчет будет тут-же показан на экране.
Скачать можно отсюда (прямая ссылка на zip-архив, ~7.2 Мб - включая prg-исходники, jodconverter, 7za.exe и DLL для работы)
http://www.maple4.ru/a_downloads_for_maple4_ru/maple4_report_generator.zip

Предлагаю потестить данное решение. Выслушаю пожелания и предложения

В бланках ODT продолжена традиция описания действий в примечаниях (т.е. точно так же, как и в ODS и XML).
В нужном месте вставляете примечание, в самом примечании - описываете необходимый код.

Код может быть так же в двух синтаксисах:
синтаксис 1 - если примечание НЕ НАЧИНАЕТСЯ с &, предполагается, что дальнейшее - код foxpro
return test_.saldo
или
return dtoc(date())
или "сложный" код (это пример, здесь можно написать что угодно )
local ii
ii=test_.saldo
return ii

синтаксис 2 - начинаясь с & - предполагается, что дальнейшее - это поле, функция или переменная
пример:
&test_.saldo
или
&dtoc(date())


Особенности бланков формата ODT
1. Отличие (от ODS и XML) написания формулы расчета суммы по колонке.
Сумма по колонке считается не по фактически нарисованной таблице в файле, а по данным источника - курсора или таблицы (в отличие от формата ODS или XML - где данные собираются прямо ИЗ ЯЧЕЕК).
Главная причина, почему это сделано - отсутствие подитогов в ODT.
Поэтому, для расчета суммы нужно записать, например:
return rowssum('test_.saldo')

или

&rowssum('test_.saldo')
т.е. указав поле, по которому сумма будет рассчитываться.
ОБРАТИТЕ ВНИМАНИЕ! 'test_.saldo' взято в скобки!
Использование функций rowsrecno() - № строки в группе/отчете и rowscount() - количество строк в группе/отчете - осталось без изменений.


2. Одна служебная колонка вместо трех.
Колонка может выполнять функцию ОБЫЧНОЙ колонки, хотя это НЕ РЕКОМЕНДУЕТСЯ - результат в этом случае НЕПРЕДСКАЗУЕМ.

3. Код FoxPro должен возвращать (оператором return - в 1 синтаксисе) значение, которое будет вставлено в генерируемый файл.

4. В бланках ODT отсутствуют управляющие операторы thisdata, thisformula, thiscomment и функция add_report() - которые использовались в ODS и XML соответственно, для указания значения ячейки, указания формулы, указания примечания и генерации нового листа книги (возможно, в дальнейшем сделаю генерацию зависимых отчетов).
Как задать значение в тексте ODT или в ячейке таблицы? Смотрите чуть ниже.

5. Значение, которое будет получено кодом FoxPro или функцией/полем/переменной может быть различных типов.
Но, при генерации в отчет ВСЕ РАВНО будет вставлено текстовое значение.

Вместо Numeric - STRTRAN(LTRIM(STR(значение,15,2)),".",",") - т.е. с 2 разрядами после запятой
Вместо Date - DTOC(значение)
Вместо DateTime - TTOC(значение)
Вместо Character - текст БЕЗ ИЗМЕНЕНИЙ
Иные типы - пустая строка - ""

Поэтому, если Вас не устраивает автоматичесое приведение к тексту - можете заранее это сделать сами.
например, для возврата ЦЕЛОГО значения ВМЕСТО
&test_.saldo
или
return test_.saldo

ВВЕДИТЕ
&str(test_.saldo)
или
return str(test_.saldo)



Рекомендации по бланкам ODT:

1. Рекомендуется перед вставкой примечания внести [[]], а уже само примечание разместить между [[ и ]]
Зачем?
Написав [[]] вы определяете стиль текста (например, цвет, размер, шрифт и т.д.), который будет сгенерен примечанием (иначе - результат может быть НЕПРЕДСКАЗУЕМ).
Ну и, кроме того, это дополнительная (но не обязательная!) метка для сигнализации - "тут есть некоторое действие!"
Кстати, символы [[ и ]] будут из конечного текста удалены.


Общие рекомендации по бланкам ODT, ODS и XML.
1. Если в процессе генерации foxpro выдает ошибку (например, неверно была написана функция в бланке) - рекомендуется после исправления ПЕРЕД запуском генератора выполнить CLOSE ALL (закрытие файлов).

2. После того, как бланк ODS или XML подготовлен, рекомендуется перед сохранением скрыть первые три служебные колонки (зачем они Вам нужны в готовом файле?).
Для ODT - уменьшить ширину колонки, если эта колонка чисто служебная (кликаете мышкой по границе столбца, далее в меню столбец - ширина - и задаете ширину 0 для нужного столбца).

3. Полученные значения (в ячейках таблиц ODS, XML, ODT и в тексте ODT) из полей, функций или переменных НЕ ДОЛЖНО содержать следующих символов (таков стандарт XML):
" & < > '
и эти символы должны быть соответственно заменены на:
&quot; &amp; &lt; &gt; &apos;

Использование "запрещенных" символов может привести к ошибке открытия сформированного файла.
Для автоматической замены можно воспользоваться специальной встроеннной функцией:
symbol2xml()
Почему этого не сделать прямо в программе генерации?
Дело в том, что в большинстве случаев, такой замены НЕ ТРЕБУЕТСЯ. Так зачем тратить на это время?

Использование symbol2xml в первом синтаксисе:
return symbol2xml(test_.notes)
или во втором
&symbol2xml(test_.notes)



Особенности конвертации файлов Open Office в другие форматы прямо из генератора отчетов.
1. Возможна конвертация ODS->XLS и ODT->DOC (о других форматах - ниже).
Но, как Вы понимаете, различие форматов ведет к некоторому различию исходных и сконвертированных файлов.
Например, ODS с картинками показывается в XLS-файле, но почему-то картинки из ODT в DOC отображаются не всегда.
Поэтому, если Вы пользуетесь Microsoft Office и не хотите потерять что-либо при конвертировании - поставьте соответствующий сервис-пак (для чтения ODS и ODT), и Вам будет счастье (заметьте, нюансы все равно остаются).
ВАЖНО! Конвертация возможна ТОЛЬКО при установленном Open Office и распакованном пакете jodconverter в каталоге jodconverter (по умолчанию уже есть в дистрибутиве, в ином случае - скачайте новую версию)!

Создание бланков для XLSX и DOCX ПОКА не планируется, так как:
а) форматы xlsx и docx слишком сложны для логического понимания КАК ИЗ ТОГО, ЧТО ЕСТЬ ПОЛУЧИТЬ НОВЫЙ ДОКУМЕНТ, т.е. не прибегая напрямую к Excel или Word. Подозреваю, что это сделано Microsoft-ом специально (файлы отлично считываются и анализируются - ЭТО ДЛЯ МЕНЯ НЕ ПРОБЛЕМА, в проге есть возможность для загрузки xlsx-файлов - при раскомментировании соответствующих строк кода)
б) нет интереса со стороны пользователей :-( , причем со стороны пользователей ЗНАЮЩИХ форматы xlsx и docx (насчет картинок никто ничего не ответил).

Как получить конвертированный файл?
Нужно ПРОСТО указать в конечном файле ИНОЕ (от расширения бланка) расширение.

Вы так же можете конвертировать файлы и в иные форматы, например:
ODS->PDF, ODS->HTML, ODT->PDF, ODT->HTML и т.д.
Полный список поддерживаемых расширений находится по адресу:
www.artofsolving.com
Самую новую версию (установлена текущая - 2.2.2) можно скачать с:
sourceforge.net

Повторюсь - результат конвертации может Вас не устроить.
НО обычно для того, что-бы проверить качество конвертирования достаточно сконвертировать файл один раз (обязательно обратите внимание на то, как отображаются картинки в конвертированном файле или вообще откажитесь от них!).
Самое "правильное" расширение для сконвертированного файла, если в дальнейшем не планируется его редактирование - это PDF. Пока не наблюдалось проблем с разным отображением оригинала и конвертированной копией

jodconverter - классная вещь, хотя бы потому, что мне не придется лезть в xlsx и docx (хотя чего там, уже почти влез...)

Но так как jodconverter требует Open Office (установите Open Office - обязательно пригодится!), это может несколько напрячь некоторых пользователей (скачать, установить...)

Поэтому, если кто подскажет бесплатную программу конвертирования хотя бы ODS->XLS(X), ODT->DOC(X) БЕЗ УСТАНОВКИ ДОПОЛНИТЕЛЬНЫХ приложений - буду безмерно рад.

Как работать с jodconverter
1. Open Office должен быть установлен в системе.

2. Необходимо внести путь к Open Office
Откройте или создайте файл soffice_folder.txt и внесите туда путь к soffice.exe

Например, у меня soffice.exe находится в каталоге C:\Program Files\OpenOffice.org 3\program, поэтому внесено:
C:\Program Files\OpenOffice.org 3\program\soffice.exe
или, например, если soffice.exe находится в каталоге d:\OpenOffice.org 3\program
D:\Program Files\OpenOffice.org 3\program\soffice.exe

3. В каталоге jodconverter программы должен размещаться распакованный дистрибутив пакета.
Если он там есть - ничего не меняйте - все должно работать и так.
Если же его там нет (или существует БОЛЕЕ новая версия на сайте), скачайте архив со страницы:
sourceforge.net

4. Распакуйте в каталог jodconverter только каталоги docs,lib,src и все файлы которые находятся рядом с этими каталогами.
Т.е. в подпапке jodconverter должны находиться КАК МИНИМУМ каталоги docs,lib,src и файл document-formats.xml!

5. В подпапке lib переименуйте jodconverter-cli-N.N.N.jar в jodconverter-cli.jar , т.е. без указания версии (N.N.N - номер текущей версии).




Разработка бланка ODT.
1. Открываете/создаете документ в формате ODT, в котором нужно разместить каркас документа.
2. В нужных местах - вставляете [[]] , а между [[ и ]] - примечание. Если примечание начинается с & - предполагается что дальше - поле, функция или переменная. В ином случае - предполагается, что дальше идет код FoxPro, который должен вернуть значение оператором return (Что, впрочем необязательно).
Например, можно разместить дату генерации отчета:
&dtoc(date())
или
return dtoc(date())

3. Если необходимо в документе разместить таблицу - рисуете ее с учетом того, что колонок будет на единицу больше (служебная колонка).
После "рисования" в служебной колонке определяете тип строки.
Например,
Thistype='reportheader' - для заголовка отчета или группы.
Thistype='detail' - для обычной строки отчета.
Thistype='reportfooter' - для строки подвала отчета или группы.
Далее, нужно определить параметры группировки.

В этой же колонке, например
Thisgroup='test_.t2'
или
Thisgroup='test_.t1'
Если Thisgroup='' или не задано - считается, что строка относится не к группе, а к отчету (заголовку или подвалу отчета).

4. После задания служебной информации нужно проставить, что Вы хотите видеть в каждой ячейке строки.
Если это обычный текст - так его и вводите.
Для размещения значения поля таблицы нужно вставить
[[]] с текстом примечания между [[ и ]] (что не обязательно, но очень рекомендуется)
В тексте примечания ячеки строки detail вписываете, например:
Return test_.saldo
(1 синтаксис)
для показа значения поля test_.saldo
или
&test_.saldo
(2 синтаксис)


Значение может быть довольно сложным, например
Return alltrim(test_.fam)+' '+alltrim(test_.im)+' '+alltrim(test_.ot)
или
&test_.t1+test_.addr

В строке reportheader или reportfooter можно разместить специальную функцию для подсчета суммы по полю таблицы, например по test_.saldo
&rowssum('test_.saldo')
или
return rowssum('test_.saldo')
Обратите внимание на кавычки - они строго необходимы, так как программа будет собирать итоги именно по этому полю, а не по значениям в генерируемой таблице (отличие от ODS и XML)!

В ячейке первой колонки первой строки для таблицы нужно определить по какому селекту/курсору эта таблица будет строиться.
В примечании пишете
Procedure Init
Select * from test into cursor test_ order by t1,t2,user_id
т.е. точно так же, как при работе с ODS/XML

В одном документе может быть несколько (решать Вам) таблиц с разных ресурсов, главное - задать в первой ячейке первой служебной колонке procedure init с кодом инициализации!

5. Уменьшите ширину служебных колонок всех таблиц до минимального уровня - мышкой (перетаскиванием) это сделать не получится, зато можно сделать по другому - кликаете мышкой по границе, выбираете столбец - ширина - и задаете ширину 0 для первой колонки.

6. Сохраняете документ, запускаете генератор, выбираете сохраненный шаблон ODT и получаете готовый документ. Все.



**********************************************************************
Замеченные "странности"
ODS
При формировании ODS с рисунком в строке, высота которой динамически меняется в зависимости от содержимого, размер рисунка по вертикали так же меняется.
Т.е. если Вы размещаете рисунок в таблице - высота строки ДОЛЖНА БЫТЬ фиксированной.
Ratings: 0 negative/0 positive

Re: Генерация отчета в ODT-файл (альтернатива docx)+конвертация отчетов в другие форматы
maple4
Автор

Сообщений: 210
Откуда: Москва
Дата: 23.09.10 09:24:23
Круто
Полное отсутствие интереса
Ratings: 0 negative/0 positive

Re: Генерация отчета в ODT-файл (альтернатива docx)+конвертация отчетов в другие форматы
BOBAN

Сообщений: 580
Откуда: Солигорск
Дата: 23.09.10 10:30:30
Велосипеды уже есть у всех.
Ratings: 0 negative/0 positive

Re: Генерация отчета в ODT-файл (альтернатива docx)+конвертация отчетов в другие форматы
maple4
Автор

Сообщений: 210
Откуда: Москва
Дата: 23.09.10 10:36:06
ну почему же никто велосипедами ОПРЕДЕЛЕННЫХ марок не делится?
Ratings: 0 negative/0 positive

Re: Генерация отчета в ODT-файл (альтернатива docx)+конвертация отчетов в другие форматы
h.i.a.

Сообщений: 4001
Откуда: Мурманск/Спб
Дата: 23.09.10 12:38:01
maple4
Круто
Полное отсутствие интереса
Интерес есть, планирую добавить к своему проекту поддержку open office, но пока есть более насущные проблемы. Тема озвучена, рано или поздно народ будет пробовать и комментировать


------------------
Ratings: 0 negative/0 positive

Re: Генерация отчета в ODT-файл (альтернатива docx)+конвертация отчетов в другие форматы
sphinx

Сообщений: 29119
Откуда: Каменск-Уральски
Дата: 23.09.10 13:23:38
Цитата:
Тема озвучена, рано или поздно народ будет пробовать и комментировать

Поддерживаю!


------------------
"Вы поступили правильно, мой друг, но, боюсь, совершили ошибку"..."(с)
Ratings: 0 negative/0 positive

Re: Генерация отчета в ODT-файл (альтернатива docx)+конвертация отчетов в другие форматы
maple4
Автор

Сообщений: 210
Откуда: Москва
Дата: 24.09.10 15:40:15
Обновил версию Maple4 Report Generator (2.1)
Скачать можно отсюда (прямая ссылка на zip-архив, ~7.2 Мб - включая prg-исходники, jodconverter, 7za.exe и DLL для работы)
http://www.maple4.ru/a_downloads_for_maple4_ru/maple4_report_generator.zip

I. Появилась поддержка многострочного текста в XML-бланках.

II. ВАЖНО! Как определить, что вставляемая Вами в odt-документ таблица является расчетной?
Когда Вы размещаете в бланке ODT расчетную таблицу (т.е. она будет формироваться на основании какого-нибудь селекта) - НЕМЕДЛЕННО и ОБЯЗАТЕЛЬНО ЗАДАЙТЕ НАЗВАНИЕ ТАБЛИЦЫ, начинающееся с report!
Иначе, таблица либо вообще генериться НЕ БУДЕТ, либо генератор выдаст ошибку при формировании.

Сделать это можно через пункты меню Таблица - Свойства таблицы , и, далее, введя, например, в поле название reportТаблица1
Повторюсь, ТОЛЬКО задав название таблицы с report в начале, Вы определяете, что это именно расчетная таблица!

Если у Вас несколько расчетных таблиц - нужно для КАЖДОЙ задать имя, начинающееся с report.
Например, reportТаблица1, reportТаблица2, и т.д. или
report1, report2, report3 и т.д.

Нюансы:
Названия расчетных таблиц не должны совпадать. К сожалению, Open Office Вас не предупредит об этом. Будьте бдительны!
Пока генератор НЕ ПОДДЕРЖИВАЕТ встроенные друг в друга расчетные таблицы! Будьте внимательны!

Страница проекта в Интернет:
http://www.maple4.ru/xmlbuilder.htm
Ratings: 0 negative/0 positive



Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 14 PaulWist zhsoft  (Гостей: 12)

© 2000-2021 Fox Club 
Яндекс.Метрика