Добавление разрыва страницы во Writer

Автор zhukovia, 4 декабря 2019, 16:11

0 Пользователи и 1 гость просматривают эту тему.

zhukovia

Пытаюсь написать в 1C составление ODT (LibreOffice) документа и почти все получилось (файл создается), но никак не могу вставить в текст разрыв страницы. Информации в интернете крайне скудно. Описание API на английском нашел, но никак не могу понять как это сделать. Подскажите, как вставить разрыв страницы в текст?
Насколько я накопал то это как то связано с "BreakType::PAGE_AFTER" но куда его "совать" ума не приложу.  :(
Я понимаю что здесь не форум по 1С но думаю что из кода итак понятно что я пытаюсь сделать. Дайте хоть почитать примеров каких нибудь.


//Создаем объект для writer
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");

//Нафиг здесь эти свойства, не знаю. Поставил как было в примере
Свойства = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
Свойства.Name = "AsTemplate";
Свойства.Value = Истина;
Args = Новый COMSafeArray("VT_VARIANT", 3);
Args.SetValue(0, Свойства);
Свойства = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
Свойства.Name = "Hidden";
Свойства.Value = Истина;
Args.SetValue(1, Свойства);

//Создаем сам объект документа
Document = Desktop.LoadComponentFromURL("private:factory/swriter", "_blank", 0, Args);

//Создаем текст в документе
TextPointer = Document.GetText();

//Создаем курсор в документе
CursorPointer = TextPointer.CreateTextCursor();

//Задаем стили текста
CursorPointer.SetPropertyValue("CharHeight", 14);
CursorPointer.setPropertyValue("CharWeight", 200);

//Вставляем заголовок и перенос строки
TextPointer.InsertString(CursorPointer, "НазваниеГлавы", false);
TextPointer.InsertControlCharacter(CursorPointer, 0, false);

//Задаем стили текста
CursorPointer.SetPropertyValue("CharHeight", 12);
CursorPointer.setPropertyValue("CharWeight", 0);
//CursorPointer.setPropertyValue("BreakType", "BreakType::PAGE_AFTER");

//Вставляем заголовок и перенос строки
TextPointer.InsertString(CursorPointer, "ТекстГлавы", false);
//TextPointer.InsertControlCharacter(CursorPointer, ControlCharacter.PARAGRAPH_BREAK, false);

//Записываем файл и закрываем объект документа
Document.storeToURL(ПутьКФайлу,Args);
Document.Close(Истина);

mikekaganski

BreakType::PAGE_AFTER - это не строка, а числовая константа - см. здесь.

Ну, и я бы не советовал использовать PAGE_AFTER (хотя оно и работает) - стандартно использовать PAGE_BEFORE в абзаце, который должен начинаться с новой страницы, а не PAGE_AFTER в том, после которого предполагается разрыв. Если сделать PAGE_AFTER, то потом пользователь будет удивлён, попытавшись добавить абзац перед разрывом :)
С уважением,
Михаил Каганский

zhukovia

Еще уточнение, а куда вставлять эту константу? Если я добавляю TextPointer.InsertControlCharacter(CursorPointer, 6, false); то ничего не происходит. Может надо какой нибудь параграф еще создавать? А то у меня, как я понимаю только Текст и Курсор есть и никакого BEFOR или AFTER нет. Я туплю скорее всего, но и правда не могу понять. Можно пример какой нибудь?

//Создаем текст в документе
TextPointer = Document.GetText();
//Создаем курсор в документе
CursorPointer = TextPointer.CreateTextCursor();

Yakov

#3
Так вроде работает

//Создаем объект для writer
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");

//Нафиг здесь эти свойства, не знаю. Поставил как было в примере
Свойства = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
Свойства.Name = "AsTemplate";
Свойства.Value = Истина;
Args = Новый COMSafeArray("VT_VARIANT", 3);
Args.SetValue(0, Свойства);
Свойства = ServiceManager.Bridge_GetStruct("com.sun.star.beans.PropertyValue");
Свойства.Name = "Hidden";
Свойства.Value = Истина;
Args.SetValue(1, Свойства);

//Создаем сам объект документа
Document = Desktop.LoadComponentFromURL("private:factory/swriter", "_blank", 0, Args);

//Создаем текст в документе
TextPointer = Document.GetText();

//Создаем курсор в документе
CursorPointer = TextPointer.CreateTextCursor();

//Задаем стили текста
CursorPointer.SetPropertyValue("CharHeight", 14);
CursorPointer.setPropertyValue("CharWeight", 200);

//Вставляем заголовок и перенос строки
TextPointer.InsertString(CursorPointer, "НазваниеГлавы", false);
TextPointer.InsertControlCharacter(CursorPointer, 0, false);

//Задаем стили текста
CursorPointer.SetPropertyValue("CharHeight", 12);
CursorPointer.setPropertyValue("CharWeight", 0);

//
CursorPointer.setPropertyValue("BreakType", 4);
TextPointer.InsertControlCharacter(CursorPointer, 6, false);
//


//Вставляем заголовок и перенос строки
TextPointer.InsertString(CursorPointer, "ТекстГлавы", false);

//Записываем файл и закрываем объект документа
Document.storeToURL(ПутьКФайлу,Args);
Document.Close(Истина);


zhukovia

#4
Большое спасибо, получилось. А не подскажите ещё немного?
1. Как добавить картинку в документ?
2. И как выровнять строку "по центру"?

bigor

Не знаю насколько правильно, но я в своих первых макросах использовал такой вариант разбивки на страницы
oTCursor.gotoEnd(false)' переходим в конец
oTCursor.PageDescName = oTCursor.PageStyleName ' вставляем новую страницу




Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

zhukovia

А чем это правильнее
Цитата: Bigor от  4 декабря 2019, 17:39oTCursor.gotoEnd(false)' переходим в конец
oTCursor.PageDescName = oTCursor.PageStyleName ' вставляем новую страницу
чем это?
Цитата: Yakov от  4 декабря 2019, 17:02CursorPointer.setPropertyValue("BreakType", 4);         
TextPointer.InsertControlCharacter(CursorPointer, 6, false);
Вроде бы все работает.

mikekaganski

Цитата: zhukovia от  4 декабря 2019, 17:57
А чем это правильнее
Цитата: Bigor от  4 декабря 2019, 17:39oTCursor.gotoEnd(false)' переходим в конец
oTCursor.PageDescName = oTCursor.PageStyleName ' вставляем новую страницу
чем это?
Цитата: Yakov от  4 декабря 2019, 17:02CursorPointer.setPropertyValue("BreakType", 4);         
TextPointer.InsertControlCharacter(CursorPointer, 6, false);
Вроде бы все работает.

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

А в варианте, предложенном Yakov, похоже, остался кусок от Ваших экспериметнов:
Цитата: Yakov от  4 декабря 2019, 17:02TextPointer.InsertControlCharacter(CursorPointer, 6, false);

TextPointer.InsertControlCharacter вставляет один из спецсимволов, перечисленных здесь, и у Вас есть вставка ControlCharacter.PARAGRAPH_BREAK (0), а вот значение 6 там не определено, и что эта строка делает - непонятно.

А без этого куска вариант Yakov должен быть правильнее для Вашего случая.
С уважением,
Михаил Каганский

zhukovia

Цитата: mikekaganski от  4 декабря 2019, 18:11CursorPointer.setPropertyValue("BreakType", 4);
Действительно, так тоже работает. Большое спасибо за поправку (не люблю мусорный код).
А по поводу других моих вопросов не подскажите?
1. Как добавить картинку в документ?
2. И как выровнять строку "по центру"? Как шрифт менять разобрался, а это не могу.
Не могу пока понять как пользоваться этим хелпом https://api.libreoffice.org/docs/idl/ref/index.html больно все непонятно.

mikekaganski

Цитата: zhukovia от  4 декабря 2019, 19:07
2. И как выровнять строку "по центру"? Как шрифт менять разобрался, а это не могу.

Попробуйте задать свойству ParaAdjust значение 1 (определено здесь).

CursorPointer.setPropertyValue("ParaAdjust", 1);
С уважением,
Михаил Каганский

bigor

Цитата: zhukovia от  4 декабря 2019, 19:07И как выровнять строку "по центру"?
Sub Main
oDoc=ThisComponent
TextPointer = oDoc.GetText()
CursorPointer = TextPointer.CreateTextCursor()
CursorPointer.SetPropertyValue("CharHeight", 14)
CursorPointer.setPropertyValue("CharWeight", 200)
TextPointer.InsertString(CursorPointer, "НазваниеГлавы", false)
TextPointer.InsertControlCharacter(CursorPointer, 0, false)
CursorPointer.setPropertyValue("ParaAdjust", 3)
TextPointer.InsertString(CursorPointer, "Насколько я накопал то это как то связано с ""BreakType::PAGE_AFTER"" но куда его ""совать"" ума не приложу.  Я понимаю что здесь не форум по 1С но думаю что из кода итак понятно что я пытаюсь сделать. Дайте хоть почитать примеров каких нибудь.", false)
End Sub


Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

bigor

Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

economist

#12
На всякий случай упомяну что самый простой и быстрый в кодинге и эксплуатации способ получить красивый отформатированный ODT/DOC из 1С и др. внешних приложений (через COM/UNO) - это не форматировать кодом текст вообще, а просто заменять кодом в уже отформатированном шаблоне "условные" строки текста на "нужные", а для обновления картинок - просто перезаписывать файлы изображений, вставленные как связи в ODT/DOC. Делать это можно не только на уровне COM/UNO автоматизации, но еще и просто заменой в zip-архиве файла ODT.

Если же документ "серийный", то еще правильнее использовать отчет 1С как источник данных (вывод в TXT), а Writer с базой данный в виде ссылки на TXT - как механизм серийной рассылки. Можно добиться легкой фильтрации "списка рассылки" путем написания SQL-запросов, в т.ч. параметрических. Плюсом данного метода является использование условного/скрытого текста Writer, который сам по себе прекрасно умеет переверстывать документ в противоположный по смыслу. То есть письмо-претензия по задолженности и письмо-благодарность за предоплату - это один и тот же ODT :-)  
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

zhukovia

Цитата: Bigor от  4 декабря 2019, 19:48CursorPointer.setPropertyValue("ParaAdjust", 3)
Спасибо, отцентрировалось. :)
Подскажите еще по последнему вопросу. Как вставить картинку в текст? Хотя бы команда как называется.

zhukovia

Цитата: economist от  5 декабря 2019, 10:03На всякий случай упомяну что самый простой и быстрый в кодинге и эксплуатации способ получить красивый отформатированный ODT/DOC из 1С и др. внешних приложений (через COM/UNO) - это не форматировать кодом текст вообще, а просто заменять кодом в уже отформатированном шаблоне "условные" строки текста на "нужные", а для обновления картинок - просто перезаписывать файлы изображений, вставленные как связи в ODT/DOC.
Возможно оно и так, но у меня совсем не серийное задание и делать шаблон не очень удобно. Опишу подробнее. Мне надо спарсить книгу с сайта в файл ODT, чтобы потом перевести в какой нибудь формат e-book (mobi, fbr2 или подобный). Руками это делать очень геморно, там оглавление на одной странице, а главы по ссылкам (в виде текста и некоторые поделены еще на части) и глав этих более 200. Поделав руками 20 глав мне это надоело и решил написать парсер (заодно и потренироваться с выводом в ODT из 1С). Нужно вставить картинку к главе и название главы по центру страницы а после содержимое главы, потом разрыв страницы и т.д. Еще хочу оглавление прикрутить с главами и ссылками на них (вроде должно быть не сложно). Уже сделал Заголовок главы по центру и сам текст главы + перенос строки. Осталось картинку и оглавление.
Поэтому если можно то подскажите как сделать или с чего начать (какие операторы применяются для этого).
Конечно все это можно сделать и руками один раз, но работы дня на 2... и к тому же лишние знания не помешают (Лучше день потерять, но потом за пять минут долететь!!) :)