Модифікації сторінки XPS на основі подій | .NET

Що таке подійний підхід у програмуванні?

Подійний підхід у програмуванні — це парадигма, яка обертається навколо концепції подій і обробки подій. У цій моделі потік програми визначається подіями, якими можуть бути дії користувача (наприклад, клацання мишею або натискання клавіш), сповіщення, створені системою, або повідомлення від інших програм. Ось деякі ключові аспекти подійного підходу:

Загалом, підхід, заснований на подіях, є потужним способом керування взаємодіями та робочими процесами в програмі, що робить його особливо ефективним для додатків, які вимагають швидкого реагування та взаємодії з користувачем.

Події, які відбуваються під час перетворення документа XPS

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

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

 1for (int i = 1; i <= document.DocumentCount; i++)
 2{
 3    document.SelectActiveDocument(i);
 4    for (j = 1; j <= document.PageCount; j++)
 5    {
 6        document.SelectActivePage(j);
 7        // Your changes ...
 8    }
 9}
10document.SaveAsPdf("file-name.pdf", saveOptions);

Якщо вам також потрібно внести деякі нерегулярні зміни перед тими, що повторюються, цей підхід може призвести до певної плутанини або надмірного обходу документів і сторінок, не кажучи вже про те, що ці цикли можуть здаватися трохи громіздкими. Коли ви перетворюєте документ XPS у формат PDF або зображення, процес відбувається сторінка за сторінкою. Коли завдання перетворення готове до обробки наступної сторінки, воно запускає подію «до сторінки». Користувач може визначити обробку таких подій, розширивши клас BeforePageSavingEventHandler, таким чином скориставшись деякими перевагами, викладеними у вступному розділі цієї статті.

Приклад додавання навігаційних гіперпосилань

Тут ми наведемо приклад, пов’язаний із випадком навігаційних гіперпосилань. І щоб зробити завдання трохи складнішим, ми перетворимо лише підмножину всіх сторінок у PDF, як зазначено у властивості PdfSaveOptions.PageNumbers.

Клас обробника подій

Нижче наведено розширення класу BeforePageSavingEventHandler:

 1/// <summary>
 2/// The class to handle the before-page event while converting an XPS document.
 3/// </summary>
 4public class NavigationInjector : BeforePageSavingEventHandler
 5{
 6    // The font in which navigation hyperlinks and page numbers will be displayed.
 7    private readonly XpsFont _font;
 8    // The page numbers to convert.
 9    private readonly SortedList<int, int> _pageNumbers;
10
11    public NavigationInjector(XpsFont font, int[] pageNumbers)
12    {
13        _font = font;
14        if (pageNumbers == null)
15            return;
16
17        // Turn the page number array into a sorted collection of unique values.
18        _pageNumbers = new SortedList<int, int>();
19        foreach (int pn in pageNumbers)
20            _pageNumbers[pn] = 0;
21    }
22
23    public override void Handle(BeforeSavingEventArgs<PageAPI> args)
24    {
25        PageAPI api = args.ElementAPI;
26
27        XpsGlyphs glyphs;
28        // For all pages in the output PDF except the first one...
29        if (args.OutputPageNumber > 1)
30        {
31            // ...insert a hyperlink to the first page...
32            glyphs = api.CreateGlyphs(_font, 15f, 5f, api.Height - 10f, "[First]");
33            glyphs.Fill = api.CreateSolidColorBrush(Color.Blue);
34            glyphs.HyperlinkTarget = new XpsPageLinkTarget(_pageNumbers == null ? 1 : _pageNumbers.Keys[0]);
35            api.Add(glyphs);
36
37            // ...and to the previous page.
38            glyphs = api.CreateGlyphs(_font, 15f, 60f, api.Height - 10f, "[Prev]");
39            glyphs.Fill = api.CreateSolidColorBrush(Color.Blue);
40            glyphs.HyperlinkTarget = new XpsPageLinkTarget(
41                _pageNumbers == null ? args.AbsolutePageNumber - 1 : _pageNumbers.Keys[args.OutputPageNumber - 2]);
42            api.Add(glyphs);
43        }
44
45        // For all pages in the output PDF except the last one...
46        if ((_pageNumbers != null && args.OutputPageNumber < _pageNumbers.Count) ||
47            (_pageNumbers == null && args.OutputPageNumber < api.TotalPageCount))
48        {
49            // ...insert a hyperlink to the next page...
50            glyphs = api.CreateGlyphs(_font, 15f, 110f, api.Height - 10f, "[Next]");
51            glyphs.Fill = api.CreateSolidColorBrush(Color.Blue);
52            glyphs.HyperlinkTarget = new XpsPageLinkTarget(
53                _pageNumbers == null ? args.AbsolutePageNumber + 1 : _pageNumbers.Keys[args.OutputPageNumber]);
54            api.Add(glyphs);
55
56            // ...and to the last page.
57            glyphs = api.CreateGlyphs(_font, 15f, 160f, api.Height - 10f, "[Last]");
58            glyphs.Fill = api.CreateSolidColorBrush(Color.Blue);
59            glyphs.HyperlinkTarget = new XpsPageLinkTarget(
60                _pageNumbers == null ? api.TotalPageCount : _pageNumbers.Keys[_pageNumbers.Keys.Count - 1]);
61            api.Add(glyphs);
62        }
63
64        // Insert a page number in the bottom-right corner.
65        glyphs = api.CreateGlyphs(_font, 15f, api.Width - 20f, api.Height - 10f, args.OutputPageNumber.ToString());
66        glyphs.Fill = api.CreateSolidColorBrush(Color.Black);
67        api.Add(glyphs);
68
69        // Add an outline entry to display the links to the converted pages in the navigation pane of a PDF viewer.
70        api.AddOutlineEntry(string.Format("Page {0}", args.OutputPageNumber), 1, args.AbsolutePageNumber);
71    }
72}

Клас обробника повинен знати про сторінки, які ми хочемо зберегти як PDF, щоб створити правильні цільові гіперпосилання. Таким чином, конструктор повинен приймати властивість масиву опцій як аргумент. Якщо вказано масив номерів сторінок, ми створюємо їх відсортовану колекцію, водночас уникаючи дублікатів. (До речі, це рішення не зовсім точне. Чи можете ви зрозуміти, що може спричинити неузгодженість у виводі?) Нам також знадобиться об’єкт XpsFont, який містить дані шрифту для тексту гіперпосилання.

Все це відбувається в перевизначеному методі Handle(). Аргумент методу — це об’єкт, який містить API модифікації для поточної сторінки, номер документа в пакеті XPS, абсолютний номер сторінки в усіх документах, відносний номер сторінки в поточному документі (який дорівнює попередній номер, якщо в пакеті лише один документ), і номер вихідної сторінки (який дорівнює абсолютному номеру сторінки, коли ми конвертуємо весь пакет).

Логіка наступних двох блоків if досить проста. Він базується на аналізі аргументу події OutputPageNumber, щоб опустити деякі посилання, де це доречно: посилання [First] і [Prev] буде додано до всіх сторінок виводу, крім першої, тоді як Посилання [Далі] та [Останнє] відображатимуться на всіх сторінках, крім останньої. Логіка також адаптована для обох випадків, незалежно від того, чи вказано номери сторінок чи ні.

Після блоків if у нижньому правому куті сторінки є код для додавання номера сторінки.

Останній рядок додає структурний запис сторінки, елемент, який відображатиметься на панелі навігації програми перегляду PDF (якщо підтримується).

Код перетворення

Тепер, коли визначено обробник події «до сторінки», ми можемо написати код, який перетворює документ:

 1// The path to the documents directory.
 2string dataDir = RunExamples.GetDataDir_WorkingWithPages();
 3// Open an XPS document
 4using (XpsDocument doc = new XpsDocument(dataDir + "Sample3.xps"))
 5// Create a font
 6using (Stream fontStream = File.OpenRead(dataDir + "arialbd.ttf"))
 7{
 8    // Create options for conversion to PDF
 9    PdfSaveOptions options = new PdfSaveOptions();
10    // Set the filter for the pages that need conversion
11    options.PageNumbers = new int[] { 2, 6, 7, 13 };
12    // Add the event handler that will execute right before the conversion of each page
13    options.BeforePageSavingEventHandlers.Add(new NavigationInjector(doc.CreateFont(fontStream), options.PageNumbers));
14    // Save resultant XPS document
15    doc.SaveAsPdf(dataDir + "ModifyPageOnConversion_out.pdf", options);
16}

Ми відкриваємо файл XPS, а потім створюємо об’єкт потоку з файлом даних шрифту. Далі ми створюємо екземпляр класу PdfSaveOptions і вказуємо кількість сторінок, які потрібно конвертувати. У наступному рядку обробник події «до сторінки» «підключається» до завдання перетворення за допомогою параметра колекції «BeforePageSavingEventHandlers».

Все, що залишилося зробити, це запустити перетворення в PDF за допомогою методу SaveAsPdf() документа.

Висновок

У цій статті ми дослідили ключові моменти подієвого підходу в програмуванні, розглянули прямий метод зміни сторінок документа XPS і навчилися більш досконалої та витонченої техніки для внесення повторюваних змін до всіх вихідних сторінок під час процес перетворення, використовуючи вставку навігаційних гіперпосилань як приклад.

Щоб отримати повні приклади, перегляньте наш Приклад проекту.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.