Modifica di una pagina XPS in base agli eventi | Java

Comprendere l’approccio basato sugli eventi nella programmazione

L’approccio basato sugli eventi nella programmazione è un paradigma incentrato sugli eventi e sulla loro gestione. In questo modello, il flusso del programma è dettato dagli eventi, che possono includere azioni dell’utente (come clic del mouse o pressione di tasti), notifiche generate dal sistema o messaggi provenienti da altre applicazioni. Di seguito sono riportati alcuni aspetti chiave dell’approccio basato sugli eventi:

Nel complesso, l’approccio basato sugli eventi è un metodo efficace per gestire le interazioni e i flussi di lavoro all’interno di un programma, rendendolo particolarmente adatto per applicazioni che richiedono reattività e interazioni con l’utente.

Conversione ed eventi del documento XPS

Quando è necessario modificare una pagina specifica di un documento XPS utilizzando l’API Aspose.Page, in genere si seleziona il documento attivo (se il file XPS contiene più documenti), si seleziona la pagina attiva e quindi si applicano le modifiche.

Ora, supponiamo di dover implementare modifiche ripetute su tutte le pagine di un file XPS e successivamente convertire il risultato in formato PDF o immagine. Esempi di tali modifiche potrebbero includere l’aggiunta di una filigrana alle pagine o l’inserimento di collegamenti ipertestuali di navigazione. Il metodo più semplice per apportare tali modifiche consiste nell’attraversare i documenti nel pacchetto XPS, le pagine del documento attivo corrente e infine applicare le modifiche. Pertanto, il codice per eseguire questa operazione sarebbe il seguente:

 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);

Se è necessario apportare anche modifiche irregolari prima di applicare quelle ricorrenti, questo approccio potrebbe generare confusione o richiedere un’eccessiva consultazione di documenti e pagine. Inoltre, questi cicli potrebbero apparire piuttosto macchinosi.

Quando si converte un documento XPS in PDF o un’immagine, il processo avviene una pagina alla volta. Mentre il processo di conversione si prepara a elaborare la pagina successiva, attiva un evento “before-page”. L’utente può definire il comportamento (gestione degli eventi) per tali eventi estendendo la classe BeforePageSavingEventHandler, sfruttando così alcuni dei vantaggi discussi nella sezione introduttiva di questo articolo.

Esempio di aggiunta di collegamenti ipertestuali di navigazione

In questa sezione, presenteremo un esempio che prevede l’uso di collegamenti ipertestuali di navigazione. Per rendere il compito un po’ più complicato, convertiremo solo un sottoinsieme di tutte le pagine in PDF, come definito dal metodo PdfSaveOptions.setPageNumbers().

La classe gestore eventi

Di seguito è riportata l’estensione della classe 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}

La classe gestore deve conoscere le pagine che intendiamo salvare in PDF per stabilire le destinazioni corrette del collegamento ipertestuale. Di conseguenza, il costruttore dovrebbe accettare la proprietà array getPageNumbers() delle opzioni come argomento. Se viene fornito l’array dei numeri di pagina, ne creiamo una raccolta ordinata, escludendo allo stesso tempo i duplicati. Inoltre, la classe necessita di un oggetto XpsFont che contenga i dati del font per il testo del collegamento ipertestuale.

Il metodo handle() sovrascritto è dove avviene tutto. L’argomento del metodo è un oggetto che contiene l’API di modifica per la pagina corrente, il numero del documento all’interno del pacchetto XPS, il numero di pagina assoluto di tutti i documenti, il numero di pagina relativo all’interno del documento corrente (che è uguale al numero precedente se il pacchetto contiene un solo documento) e il numero di pagina di output (che è uguale al numero di pagina assoluto quando convertiamo l’intero pacchetto).

La logica dei due blocchi if seguenti è piuttosto semplice. Analizza l’argomento dell’evento getOutputPageNumber() per omettere alcuni link, ove appropriato: i link [First] e [Prev] non verranno aggiunti alla prima pagina, mentre i link [Next] e [Last] non appariranno nell’ultima pagina. La logica è inoltre progettata per gestire entrambi gli scenari, indipendentemente dal fatto che i numeri di pagina siano specificati o meno.

Dopo i blocchi if, c’è del codice che aggiunge un numero di pagina nell’angolo in basso a destra della pagina.

L’ultima riga aggiunge la voce di struttura della pagina, che è l’elemento che verrà visualizzato nel riquadro di navigazione di un visualizzatore PDF (se supportato).

Codice per la conversione

Ora che il gestore dell’evento “before-page” è definito, possiamo scrivere il codice per la conversione del documento:

 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}

Apriamo un file XPS e creiamo un oggetto stream con il file di dati del font. Successivamente, istanziamo la classe PdfSaveOptions e specifichiamo i numeri di pagina da convertire. La riga seguente “collega” il gestore dell’evento “before-page” al processo di conversione tramite la collection getBeforePageSavingEventHandlers().

Ora non ci resta che eseguire la conversione in PDF utilizzando il metodo saveAsPdf() del documento.

Conclusione

In questo articolo abbiamo trattato gli aspetti fondamentali dell’approccio basato su eventi nella programmazione, esaminato il metodo diretto per modificare le pagine di un documento XPS e analizzato una tecnica più avanzata per apportare modifiche ripetute a tutte le pagine di output durante il processo di conversione, utilizzando come esempio l’inserimento di collegamenti ipertestuali di navigazione.

Per gli esempi completi, esplora il nostro Progetto di esempio.

Have any questions about Aspose.Page?



Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.