Изменение XPS-страницы событий | Java

Понимание событийного подхода в программировании

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

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

Преобразование документов XPS и события

Когда вам нужно изменить определенную страницу документа XPS с помощью API Aspose.Page, вы обычно выбираете активный документ (если в файле XPS несколько документов), выбираете активную страницу, а затем применяете изменения.

Теперь предположим, что вам нужно реализовать повторяющиеся изменения на всех страницах файла XPS и впоследствии преобразовать результат в формат PDF или изображение. Примеры таких изменений могут включать добавление водяных знаков на страницы или вставку навигационных гиперссылок. Простой метод внесения таких изменений включает в себя просмотр документов в пакете XPS, просмотр страниц текущего активного документа и затем, наконец, применение ваших изменений. Таким образом, код для решения этой задачи будет выглядеть следующим образом:

 1for (int i = 1; i <= document.getDocumentCount(); i++)
 2{
 3    document.selectActiveDocument(i);
 4    for (j = 1; j <= document.getPageCount(); j++)
 5    {
 6        document.selectActivePage(j);
 7        // Your changes ...
 8    }
 9}
10document.saveAsPdf("file-name.pdf", saveOptions);

Если вам также необходимо внести некоторые нерегулярные изменения перед применением повторяющихся, этот подход может привести к путанице или чрезмерному перемещению по документам и страницам. Кроме того, эти петли могут показаться несколько громоздкими. Когда вы конвертируете документ XPS в PDF или изображение, процесс происходит по одной странице за раз. Когда задание преобразования готовится к обработке следующей страницы, оно запускает событие «до страницы». Пользователь может определить поведение (обработку событий) для таких событий, расширив класс BeforePageSavingEventHandler, тем самым воспользовавшись некоторыми преимуществами, обсуждаемыми во вводном разделе этой статьи.

Пример добавления навигационных гиперссылок

В этом разделе мы представим пример навигационных гиперссылок. И чтобы немного усложнить задачу, мы преобразуем в PDF только часть всех страниц, как определено методом PdfSaveOptions.setPageNumbers().

Класс обработчика событий

Ниже показано расширение класса BeforePageSavingEventHandler:

 1/**
 2 * The class to handle the before-page event while converting an XPS document.
 3 */
 4public static class NavigationInjector extends BeforePageSavingEventHandler
 5{
 6    private final XpsFont _font;
 7    private List<Integer> _pageNumbers;
 8
 9    public NavigationInjector(XpsFont font, int[] pageNumbers)
10    {
11        _font = font;
12        if (pageNumbers == null || pageNumbers.length == 0)
13            return;
14
15        // Turn the page number array into a sorted collection of unique values.
16        SortedMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
17        for (int pn : pageNumbers)
18            map.put(pn, 0);
19        _pageNumbers = new ArrayList<Integer>(map.keySet());
20    }
21
22    /**
23     * The action itself to be triggered on a before-page event.
24     * @param args The even arguments.
25     */
26    @Override
27    public void handle(BeforeSavingEventArgs<PageAPI> args)
28    {
29        PageAPI api = args.getElementAPI();
30
31        XpsGlyphs glyphs;
32        // For all pages in the output PDF except the first one...
33        if (args.getOutputPageNumber() > 1)
34        {
35          // ...insert a hyperlink to the first page...
36            glyphs = api.createGlyphs(_font, 15f, 5f, api.getHeight() - 10f, "[First]");
37            glyphs.setFill(api.createSolidColorBrush(Color.BLUE));
38            glyphs.setHyperlinkTarget(new XpsPageLinkTarget(_pageNumbers == null ? 1 : _pageNumbers.get(0)));
39            api.add(glyphs);
40
41            // ...and to the previous page.
42            glyphs = api.createGlyphs(_font, 15f, 60f, api.getHeight() - 10f, "[Prev]");
43            glyphs.setFill(api.createSolidColorBrush(Color.BLUE));
44            glyphs.setHyperlinkTarget(new XpsPageLinkTarget(
45                _pageNumbers == null ? args.getAbsolutePageNumber() - 1 : _pageNumbers.get(args.getOutputPageNumber() - 2)));
46            api.add(glyphs);
47        }
48
49        // For all pages in the output PDF except the last one...
50        if ((_pageNumbers != null && args.getOutputPageNumber() < _pageNumbers.size()) ||
51            (_pageNumbers == null && args.getOutputPageNumber() < api.getTotalPageCount()))
52        {
53          // ...insert a hyperlink to the next page...
54            glyphs = api.createGlyphs(_font, 15f, 110f, api.getHeight() - 10f, "[Next]");
55            glyphs.setFill(api.createSolidColorBrush(Color.BLUE));
56            glyphs.setHyperlinkTarget(new XpsPageLinkTarget(
57                _pageNumbers == null ? args.getAbsolutePageNumber() + 1 : _pageNumbers.get(args.getOutputPageNumber())));
58            api.add(glyphs);
59
60            // ...and to the last page.
61            glyphs = api.createGlyphs(_font, 15f, 160f, api.getHeight() - 10f, "[Last]");
62            glyphs.setFill(api.createSolidColorBrush(Color.BLUE));
63            glyphs.setHyperlinkTarget(new XpsPageLinkTarget(
64                _pageNumbers == null ? api.getTotalPageCount() : _pageNumbers.get(_pageNumbers.size() - 1)));
65            api.add(glyphs);
66        }
67
68        // Insert a page number in the bottom-right corner.
69        glyphs = api.createGlyphs(_font, 15f, api.getWidth() - 20f, api.getHeight() - 10f, Integer.toString(args.getOutputPageNumber()));
70        glyphs.setFill(api.createSolidColorBrush(Color.BLACK));
71        api.add(glyphs);
72
73        // Add an outline entry to display the links to the converted pages in the navigation pane of a PDF viewer.
74        api.addOutlineEntry(MessageFormat.format("Page {0}", args.getOutputPageNumber()), 1, args.getAbsolutePageNumber());
75    }
76}

Класс-обработчик должен знать о страницах, которые мы собираемся сохранить в формате PDF, чтобы установить правильные цели гиперссылок. Следовательно, конструктор должен принимать свойство массива options getPageNumbers() в качестве аргумента. Если предоставлен массив номеров страниц, мы создаем их отсортированную коллекцию, одновременно исключая дубликаты. Кроме того, классу нужен объект XpsFont, содержащий данные шрифта для текста гиперссылки.

Все это происходит в переопределенном методе handle(). Аргументом метода является объект, который содержит API модификации для текущей страницы, номер документа в пакете XPS, абсолютный номер страницы во всех документах, относительный номер страницы в текущем документе (который равен предыдущий номер, если в пакете только один документ) и номер выходной страницы (который равен абсолютному номеру страницы при преобразовании всего пакета).

Логика следующих двух блоков if довольно проста. Он анализирует аргумент события getOutputPageNumber(), чтобы опустить некоторые ссылки, где это необходимо: ссылки [First] и [Prev] не будут добавлены на первую страницу, а [Next] и Ссылки [Last] не будут отображаться на последней странице. Логика также предназначена для реализации обоих сценариев, независимо от того, указаны номера страниц или нет.

После блоков if идет код, который добавляет номер страницы в правом нижнем углу страницы.

Последняя строка добавляет запись структуры страницы, которая представляет собой элемент, который будет отображаться в области навигации средства просмотра PDF (если поддерживается).

Код для конвертации

Теперь, когда обработчик события «перед страницей» определен, мы можем написать код для преобразования документа:

 1// For complete examples and data files, please go to https://github.com/aspose-page/Aspose.Page-for-Java
 2// The path to the documents directory.
 3String dataDir = Utils.getDataDir();
 4String fontDir = dataDir + "necessary_fonts/";
 5// Open an XPS Document
 6final XpsDocument doc = new XpsDocument(dataDir + "Sample3.xps");
 7try {
 8  // Create a font
 9  final InputStream fontStream = new FileInputStream(fontDir + "arialbd.ttf");
10  try {
11    // Create options for conversion to PDF
12    PdfSaveOptions options = new PdfSaveOptions();
13    // Set the filter for the pages that need conversion
14    options.setPageNumbers(new int[] { 2, 6, 7, 13 });
15    // Add the event handler that will execute right before the conversion of each page
16    options.getBeforePageSavingEventHandlers().add(new NavigationInjector(doc.createFont(fontStream), options.getPageNumbers()));
17    // Save resultant XPS document
18    doc.saveAsPdf(dataDir + "ModifyPageOnConversion_out.pdf", options);
19  } finally {
20    if (fontStream != null)
21      fontStream.close();
22  }
23} finally {
24  if (doc != null)
25    doc.close();
26}

Мы открываем файл XPS, а затем создаем объект потока с файлом данных шрифта. Затем мы создаем экземпляр класса PdfSaveOptions и указываем номера страниц, которые нам нужно преобразовать. Следующая строка «подключает» обработчик событий «before-page» к заданию преобразования через коллекцию getBeforePageSavingEventHandlers().

Все, что осталось сделать, это запустить преобразование в PDF, используя метод saveAsPdf() документа.

Заключение

В этой статье мы рассмотрели фундаментальные аспекты событийно-ориентированного подхода в программировании, рассмотрели прямой метод изменения страниц документа XPS и изучили более продвинутый метод внесения повторяющихся изменений во все выходные страницы в процессе преобразования. , на примере вставки навигационных гиперссылок.

Полные примеры можно найти в нашем Пример проекта.

Have any questions about Aspose.Page?



Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.