Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Свежие комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 22 ноября 2009 в 20:16.
Категории: Без категории, Моя работа.


pinguin LinuxКак я уже отмечал в блоге, есть планы прейти на программирование в Lazarus. Учитывая, что уже сейчас решается вопрос о том, чтобы перевести все машины на работе под управление Linux с нового года, можно начинать чесать репу и думать каким макаром перегнать большой программный комплекс для экологов поту же Ubuntu. Самая острая проблема - документы. Как ни крути, а отчёт созданный в том же Excel или Word, выглядит намного более привлекательно, чем простой текстовик. Посмотрим, что можно предпринять в случае работы под Linux не потерять презентабельность документов.

В принципе вариантов не так уж и много.

Первый вариант - генерировать простой html-файл. Достоинство этого подхода очевидно - простота при разработке программ. Если учесть, что Lazarus вполне хорошо справляется с DOM, то есть возможность не только выдавать документ на печать, но и, в случае необходимости, проводить его анализ.

Недостаток подобного подхода - достаточно трудно сформировать удобочитаемый документ, если в нем встречается большое количество формул, диаграмм и т.д.

Второй вариант - использовать возможности OpenOffice. На данный момент этот вариант мне больше всего нравится. Что сразу бросилось в глаза при изучении документации по OO - это то, что в документе математические формулы храняться точно также как и простой текст. То есть сразу появляется куча возможностей по формированию сложных по составу и содержанию отчётов и документов.

Помниться, когда только начинал разрабатывать первую версию программы, не мог понять как работать из Delphi с MathType (надстройка в office для рисования формул). В итоге, так и не поняв как это делается писал все формулы в строку простым текстом - корявенько и топорно, но читаемо. С OpenOffice + Lazarus все по другому - можно расписывать хоть 10-ти этажные дроби.

Дополнительным стимулом к использованию форматов OpenOffice послужило также то, что в этом случае можно создать 100% кросплатформенный проект и уже не заморачиваться над тем, какую ОС задумают поставить админы на машинах в следующем году - OpenOffice без проблем работает везде.

Посмотрим, что из себя в принципе представляет документ OpenOffice, например, возьмем файл Writer'а *.odt (аналог Word).

1. Формат Open Document

Собственно, для тех, кто имеет хотя бы общие представления об устройстве XML-файла, не составит особого труда разобраться и с форматом Open Document.

Дело в том, что любой документ из OpenOffice (текстовый, таблица, презентация, формула) представляет собой простой zip-архив внутри которого содержаться XML-файлы, каждый из которых содержит какую-либо информацию о документе.

Более того, само содержание и расположение файлов в архиве чертовски напоминает мне сайты на narod.ru :). Вот, например, содержимое файа *.odt в котором содержится всего одна строка по центру страницы - "hello world"

odt файл

Тут, наверное, разберется даже ребенок, что основное содержимое документа располагается в файле content.xml. Посмотрим, как выглядит наша строка Hello world". Открываем файл в браузере и видим:

xml odt

Всё те же знакомые узлы XML и не менее знакомые атрибуты типа center и пр.
Получается следующее. Если необходимо создавать документы по какому-либо шаблону (что мне наиболее часто и приходится делать), то достаточно накидать шаблон документа и распакавать его в какую-либо папку, затем уже в своей программе открыть нужный xml-файл, изменить и запокавать обратно в zip-архив, но с расширением файла Open Document. И никаких тебе OLE и т.д. и т.п. Организуется всё элементарно и без каких-либо сторонних компонентов.
Если же Вам требуется разрабатывать документы какого-нибудь уникального содержания, то тут Вам, как ни крути, придётся с головой окунуться в документацию по Open Document Format. Благо такая документация есть в открытом доступе и скачать её можно, например здесь.

Итак, первый шаг к разработке кроссплатформенного проекта сделан - определились с форматами документов и в общих чертах представляем себе алгоритм работы.
Остается решить вопрос с тем, как паковать документ? Использоать dll, какой-либо компонент или обойтись тем, что есть в Lazarus?

2. Работа с архивами в Lazarus

Лично я сторонник того подхода к разработке любых программ, при котором по возможности не используются какие-либо сторонние компоненты - только "родные" компоненты и модули.
Это обстоятельство избавляет как минимум от одного геморроя - не надо за собой везде тягать тучу сторонних компонентов, чтобы проект без проблем открывался на любом компьютере.
Так и в случае работы с архивами в Lazarus - никто нам не запрещает воспользоваться компонентами, например с этой страницы Wiki Lazarus. Но зачем накручивать лишние компоненты, когда для работы с zip-архивами в составе Lazarus есть вполне понятная и простая в использовании утилита ZIP?
Воспользуемся ей, а заодно посмотрим, как можно обойтись в работе со сторонними приложениями без всяких ShellExecute, ShellAPI и пр.

Итак, пишем свой первый кроссплатформенный архиватор, который потом будем использовать для сборки документов OpenOffice.
Открываем Lazarus, создаем новые проект и, для наглядности работы программы, укладываем на форму две кнопки и Memo.
Самый простой вариант работы с утилитами наподобие zip и unzip - это использовать в Win32 пакетные файлы DOS (*.bat), а в Linuх - bash-скрипты. Смысл работы прост как три копейки:
1. В зависимости от того в какой ОС запущена программа, создаем либо файл скрипта с расширением sh, либо bat-файл
2. Выполняем скрипт, который пакует необходимые файлы в документ.

Разрабатываем скрипт.

Думаю, что тем, кто знаком с Linux, написать скрипт для упаковки папки в архив потребуется на всё пара минут, а то и меньше. Текст скрипта выглядит следующим образом:

#!/bin/bash
cd /путь/до/папки/с_файлами
zip -r Документ.расширение * 

Обращу Ваше внимание, что переход в папку с докуменами необходим, т.к. если просто указать утилите zip расположение файлов, то в итоге в архив будет записан весь путь до файлов и документ просто не распознается как Open Document.
В случае с bat-файлов всё также просто и понятно:

CD Полныйпутьдопапки
Полныйпутьк_утилитеzip -r Document.расширение Полныйпутьдопапки

Оба файла работают абсолютно идентично - пакуют всю папку, содержащую xml-файлы документа в один архив.
Со вспомогательной частью покончено. Переходим в Lazarus.

Первое, что необходимо - это написать обработчик одной из кнопок для создания необходимого нам файла в зависимости от ОСи. У меня получился следующий код:

procedure TForm1.Button2Click(Sender: TObject);
var F: TextFile;
begin
  AssignFile(F, ExtractFilePath(Application.ExeName)+'mybash.sh');
  Rewrite(F);
  {$IFDEF LINUX}
  WriteLn(F, '#!/bin/bash');
  WriteLn(F, 'cd '+ExtractFilePath(Application.ExeName)+'document');
  WriteLn(F, 'zip -r doc.odt *');
  CloseFile(F);
Memo1.Lines.LoadFromFile(ExtractFilePath(Application.ExeName)+'mybash.sh');
  {$ENDIF}
  {$IFDEF WIN32}
    WriteLn(F, 'CD '+ExtractFilePath(Application.ExeName)+'document');
    WriteLn(F, ExtractFilePath(Application.ExeName)+'zip -r doc.odt '+
      ExtractFilePath(Application.ExeName)+'document');
    CloseFile(F);
Memo1.Lines.LoadFromFile(ExtractFilePath(Application.ExeName)+'mybash.bat');
  {$ENDIF}
end;

Обратите внимание, что для того, чтобы узнать под какой ОС мы запустили программу, нам не требуется изгаляться и писать лишние процедуры и функции - достаточно использовать простенькие директивы "{$IFDEF}" и "{$ENDIF}".
В представленном обработчике в зависимости от операционной системы в которой запущено приложение создается свой файл для упаковки папки с xml-файлами документа и содержимое файла выводится в Memo.
Теперь посмотрим, как под Lazarus'ом можно запускать сторонние приложения.

Запуск скриптов и bat-файлов из своей программы.

Для того, чтобы запустить любую программу или выполнить скрипт в своем приложении и при этом не нарушить кроссплатформенность, в Lazarus предусмотрено использование класса TProcess или, кому удобнее использовать компоненты, сразу три невизуальных компонента TProcess* cо вкладки System:

компоненты process

Укладываем на форму самы простой из трех компонентов - TProcess и в обработчике второй кнопки пишем:

procedure TForm1.Button1Click(Sender: TObject);
begin
  {$IFDEF LINUX}
    Process1.CommandLine:='/bin/bash '+ExtractFilePath(Application.ExeName)+'mybash.sh';
  {$ENDIF}
  {$IFDEF WIN32}
    Process1.CommandLine:='cmd '+ExtractFilePath(Application.ExeName)+'mybash.bat';
  {$ENDIF}
  Process1.Options:=[poWaitOnExit];
  Process1.Execute;
end;

Здесь опять же, как мне кажется, особых сложностей нету - в зависимости от операционной сисемы запускаем на выполнение нужный файлик и ожидаем окончания выполнения. Аналогичным образом можно запускать абсолютно любые программы и приложения, отслеживать вывод консольных программ и т.д. и т.п. Чтобы лишний раз не повторяться и копипастить чужой текст - я просто скажу, что более подробно с работай компонента TProcess Вы всегда можете ознакомиться в Wiki Lazarus.
Вот теперь у нас в руках есть всё необходимое для работы с документами в любой операционной системе. Главное, не забудтся перенести утилиту zip.exe, входящую в сосав Lazarus к себе в проект.
Какие выводы можно сделать? Во-первых, работа с документами в Lazarus и OpenOffice, лично для меня оказалась намного проще, чем я ожидал. Всё, что требуется - разработать грамотный шаблон и потом немного поработать с XML. Во-вторых, использование утилиты zip избавляет нас от использования сторонних компонентов (не дай бог езё и платных). В-третьих, разработка кроссплатформенного приложения для работы с документами оказалась опять же не сложнее, чем под чисто под Win32 - достаточно не забывать про элементарные директивы компилятора. Так что, если Вас вдруг постинет та же проблема, что и меня - переход под другую ОС, то можете сильно не переживать - организовать документоооборот будет не сложнее, а даже в некотором смысле проще, чем для Win32 с использованием Microsoft Office.
Ещё одним способом кроссплатформенного документооборота является использование, например документов Google или других сетевых технологий. Кстати, нашел интересные статьи о хостинге - могут Вам помочь выбрать хостинг для Вашего кроссплатформенного проека.

Мой блог находят по следующим фразам

Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

Комментарии (10)

WP_Cloudy
  • Игорь пишет:

    Спасибо, в целом интересно, но немного не точен следующий момент. Ваша цитата:
    ===========
    Обратите внимание, что для того, чтобы узнать под какой ОС мы запустили программу, нам не требуется изгаляться и писать лишние процедуры и функции – достаточно использовать простенькие директивы “{$IFDEF}” и “{$ENDIF}”.
    ===========

    Насколько я понимаю, лучше написать «чтобы узнать под какой ОС мы КОМПИЛИРУЕМ программу». Иначе возникнет ощущение, что скомпилированная программа будет работать в обеих операционках

  • Vlad пишет:

    Да, полностью согласен, именно, чтобы узнать по какой ОС компилируем программу.

  • С. Дмитрий пишет:

    Автору большое спасибо за статью! Очень интересная информация а главное полезная ! Интересно было узнать что  *.odt обычный zip архив. Да и Lazarus  с каждым выходом хорошеет

  • Al пишет:

    docx тоже зип

  • AndyPanda пишет:

    Если директория до скрипта содержит пробелы, то необходимо:
    Process1.CommandLine:=’/bin/bash «/home/user/Lazarus projects/zumas backuper/zumas scripts/save»‘;
    Как видно .sh к скрипту приписывать нет надобности.

  • Дмитрий пишет:

    Автору огромная благодарность за проделанную работу и статью.
    После изучения все стало просто и понятно, что и как устроено.

  • AndyPanda пишет:

    Попробовал скрипт запустить в WIN32. Не пашет, потому как нужно вот так писать:


    Process1.CommandLine := 'cmd /c "' + ExtractFilePath(Application.ExeName) + 'mybatORmycmd.cmd)' + '"';

    PS: Аффтар, пробуй код перед публикацией.

  • AndyPanda пишет:

    прим: скобка лишняя ‘mybatORmycmd.cmd:)’

  • Vlad пишет:

    Вообще-то проверяю. И конкретно этот код работает в Linux

  • Konstantin пишет:

    Народ сделал как в примере ничего не понял, прошу не издеваться а более конкретно рассказать

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник

   


интернет магазин --|--. программы андроид