Войти
 
 
   
 
  
Новости Notes.ру Библиотека Биржа труда Вопрос - ответ Форум Регистрация Поиск О проекте
Разделы
О Notes
Советы
Шаблоны и примеры
Литература
Презентации
 
Всё о задаче AdminP. Часть вторая   Во второй части мы завершаем рассмотрение AdminP. В ней рассмотрены запросы междоменного администрирования и способы управления функциями AdminP с помощью настроек документа сервера, команд консоли сервера, файла Notes.ini и интервалов очистки базы данных. В этой статье предполагается, что вы опытный администратор Domino и прочитали первую часть
О Notes Читать статью
 
Всё о задаче AdminP. Proxy-действия в R5 и Domino 6   Приложение к статье об административном процессе
О Notes Читать статью
 
Всё о задаче AdminP. Часть первая   Перевод классической статьи 2003-его года о задаче административного процесса (AdminP). Очень полезна для понимания работы механизма этой задачи. В первой части статьи описаны компоненты задачи AdminP, как они работают, и как их использование помогает сделать работу администратора Domino проще. Задача AdminP (сакращённо от Administration Process, Административный процесс) работает с базой административных запросов (Administration Requests, admin4.nsf)
О Notes Читать статью
 


Шаблоны и примеры

Главная   Библиотека   Шаблоны и примеры

Java в Domino. Небольшой пример обработки потока

Николай Норкин

г. Киров

notesnet@notesnet.ru

В качестве примера, иллюстрирующего обработку файловых данных на уровне потока, можно рассмотреть манипуляции, связанные с внесением информации в электронную таблицу формата XLSX (Microsoft Excel 2003)

Задача - ежедневно формировать отчёт по данным приложения Notes в электронной таблице Microsoft Excel. Бланк таблицы уже существует, программно необходимо заполнить некоторые ячейки таблицы. В частности, ячейку с датой построения отчёта - ячейку C2 на первом листе книги Microsoft Excel

Требуется оговориться, что данная задача не предусматривает выхода за границы размеченного бланка, заполнения каких-то списковых отчётов. Бланк электронной таблицы можно назвать условно табелем с заранее обозначенным и отформатированным количеством строк и столбцов. Таким образом, отсекается необходимость что-то знать о формате электронной таблицы MS Excel (кроме, разве того факта, что значение даты записывается целым числом). Более близкое знакомство с форматом XLSX откладывается до лучших времён

Подготовка бланка отчёта

Предварительно нужно подготовить файл отчёта Отчёт.xlsx

Требуется открыть файл в приложении Micrisift Excel, установить формат ячейки С2 как формат даты (чтобы не было недоразумений - в ячейку будет записано числовое представление даты), сохранить файл

Затем нужно открыть файл отчёта в программе-архиваторе как архив zip и разделить его на две части, переместив из него файл sheet1.xml

Открыть файл sheet1.xml в текстовом редакторе или редакторе XML-файлов и задать дополнительный атрибут ячейке C2

<row r="2" spans="1:22" ht="29.25" customHeight="1" thickBot="1">

<c r="A2" s="27" t="s"><v>70</v></c>

<c r="C2" s="34" id="today"/>

<c r="G2" s="22"/>

<c r="H2" s="35" t="s"><v>64</v></c>

После этого, и "покоцанный" файл Отчёт.xlsx, и файл sheet1.xml разместить в виде файловых ресурсов в дизайне приложения

Замечание. Из описанного выше критичным является только установка формата ячейки. Парсинг архива можно реализовать и программно. А одну ячейку найти по атрибуту r, но в реальной задаче, требующей заполнения множества значений, соответствие ячейки и данных задать на программном уровне может быть значительно сложнее, чем на уровне шаблона

Программный код, решающий задачу заполнения бланка табеля

Для манипулирования потоками в предлагаемом решении используется библиотека Memo, описанная в этом материале. Для работы с zip-архивом - пакет java.util.zip

Шаг 1. Получить XML-представление файлового ресурса sheet1.xml

org.w3c.dom.Document xml = this.getSheet("sheet1.xml");

protected org.w3c.dom.Document getSheet(String filename) {

org.w3c.dom.Document xml = null;

try {

ru.medkirov.mail.File factory = new ru.medkirov.mail.File(this.session, this.database);

ru.medkirov.mail.FileResource file = factory.getFileResource(filename);

String base64 = file.getResource();

byte[] decodeBase64 = com.ibm.xml.enc.dom.Base64.decode(base64.getBytes());

return this.stringToDocument(decodeBase64);

}

catch (Exception e) {}

return xml;

}

private org.w3c.dom.Document stringToDocument(byte[] xml) {

try {

            javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();  

            javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();

            return builder.parse( new java.io.ByteArrayInputStream(xml));

}

catch (Exception ex) {

ex.printStackTrace();

}

return null;

}

Шаг 2. Записать в ячейку значение текущей даты

javax.xml.xpath.XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();

org.w3c.dom.Element cell = (org.w3c.dom.Element)xpath.evaluate("//c[@id='today']", xml, javax.xml.xpath.XPathConstants.NODE);

this.fillCell(xml, cell, Long.toString(this.getDayCount(new java.util.Date())));

protected static void fillCell(org.w3c.dom.Document document, org.w3c.dom.Element cell, String value) {

try {

if (cell == null) return;

org.w3c.dom.Element element = document.createElement("v");

cell.appendChild(element);

element.appendChild(document.createTextNode(value));

}

catch (Exception e) {

// e.printStackTrace();

}

}

public static long getDayCount(java.util.Date dateEnd) { // Дата в MS Excel представлена в виде целого числа, равного количеству дней, прошедших с 31 декабря 1899 года

 long diff = -1;

 try {

java.util.Calendar calendar = java.util.GregorianCalendar.getInstance();

calendar.set(1899, 11, 31, 0, 0, 0);

java.util.Date dateStart = calendar.getTime();

   //time is always 00:00:00 so rounding should help to ignore the missing hour when going from winter to summer time as well as the extra hour in the other direction

diff = Math.round((dateEnd.getTime() - dateStart.getTime()) / (double) 86400000);

 } catch (Exception e) {}

 return diff;

}

}

Шаг 3. Собрать файл отчёта

String xlsx = this.pack(xml, "Отчёт.xlsx");

protected String pack(org.w3c.dom.Document sheet, String filename) {

try {

ru.medkirov.mail.File factory = new ru.medkirov.mail.File(this.session, this.database);

ru.medkirov.mail.FileResource file = factory.getFileResource(filename);

String base64 = file.getResource();

byte[] decodeBase64 = com.ibm.xml.enc.dom.Base64.decode(base64.getBytes());

java.util.zip.ZipInputStream zip = new java.util.zip.ZipInputStream(new java.io.ByteArrayInputStream(decodeBase64));

java.io.ByteArrayOutputStream copyStream = new java.io.ByteArrayOutputStream();

java.util.zip.ZipOutputStream newZip = new java.util.zip.ZipOutputStream(copyStream);

newZip.setLevel(java.util.zip.ZipOutputStream.DEFLATED);

// копировать

java.util.zip.ZipEntry entry = (java.util.zip.ZipEntry) zip.getNextEntry();

java.util.zip.ZipEntry clone;

while ( entry != null ){

clone = new java.util.zip.ZipEntry(entry.getName());

clone.setComment(entry.getComment());

clone.setExtra(entry.getExtra());

clone.setMethod(entry.getMethod());

newZip.putNextEntry(clone);

            if (!entry.isDirectory()) {

java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(1024);

byte[] buf = new byte[1024];

int len = zip.read(buf);

while (len > 0) {

baos.write(buf, 0, len);

    len = zip.read(buf);

}

                copy(new java.io.ByteArrayInputStream(baos.toByteArray()), newZip);

            }

            newZip.closeEntry();

entry = (java.util.zip.ZipEntry) zip.getNextEntry();

}

// добавить sheet

clone = new java.util.zip.ZipEntry("xl/worksheets/sheet1.xml");

newZip.putNextEntry(clone);

String xml = this.xmlToString(sheet);

copy(new java.io.ByteArrayInputStream(xml.getBytes(java.nio.charset.Charset.forName("UTF-8"))), newZip);

newZip.closeEntry();

// закрыть поток

newZip.flush();

newZip.close();

base64 = javax.xml.bind.DatatypeConverter.printBase64Binary(copyStream.toByteArray());

return base64;

}

catch (Exception e) {

e.printStackTrace();

}

return "";

}

Шаг 4. Отправить отчёт по почте (используя библиотеку Memo)

ru.medkirov.mail.Memo memo = this.createMemo();

try { memo.setSubject("Ежедневный отчёт по данным приложения Lotus Notes");}   catch (Exception e) {}

if (!xlsx.equals(""))

memo.addFile(xlsx, "Ежедневный отчёт.xlsx");

memo.send();

protected ru.medkirov.mail.Memo createMemo() {

ru.medkirov.mail.Memo memo = new ru.medkirov.mail.Memo(this.session);

try {

  memo.createMemo();

  memo.setSender("Почта сервисов/Почта", "CN=Почта сервисов/O=Почта@Medical", "Агент интеграции<services-mail@acme.corp>", "services-mail@acme.corp");

  memo.setRecipients(this.getRecipients());

  memo.println("Получены данные");

}

catch (Exception e) {}

return memo;

}

protected java.util.Vector getRecipients() {

try {

java.util.Vector vector = new java.util.Vector();

vector.add("CN=Отчёты по данным приложения/O=Рассылка");

return vector;

}

catch (Exception e) {}

return null;

}

Ссылки

Java в Domino. Вывод в поток присоединённых файлов

Java в Domino. Получение файловых элементов дизайна приложений Domino в виде потоковых данных

Java в Domino. Сохранение файлового потока в документе Notes

Java в Domino. Библиотека Memo

Код библиотеки Memo
 
  Опубликовано — 01/31/2021 |    



Добавить комментарий
Имя * :
e-mail
Комментарий * :
Код подтверждения * :


Мероприятия
Пресс-релизы
Биржа труда
Последнее на форуме
 
А так же:
Как удалить профиль?
16.04.2016 00:08:51
Скопировать в буфер поле документа
24.05.2015 08:55:52
Импорт DXL-описания документов в Lotus Domino. Одноимённые поля
16.04.2015 16:49:58
 
© LOGOSPHERE.RU