|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
[iText (C# o Java)]rimuovere pagine da pdf
Ciao a tutti
Qualcuno di voi che usa le librerie iText (per java o per .net) saprebbe indirizzarmi su come poter rimuovere delle pagine da un pdf composto da più pagine ? Su di un link ho letto che: Codice:
One way to do it: Delete = Copy PDF pages and skip pages to be removed thereby leaving the pages you want. Sto provando a ragionarci su in pseudo codice: Codice:
input: 1) pdf di origine 2) pagine da non copiare elaborazione: dal pdf di origine prendo il numero di pagine che lo compongono le pagine da non copiare le memorizzo in un dizionario o in una lista o un semplice array ciclare (ma non so come) avendo come: start = 0 ; end < numeroPaginePdf ; contatore++ se contatore = numeroPaginaDaScartare, contatore +1 output: pdf - pagineScartate Grazie mille RaouL. EDIT: posto il ragionamento in codice: Codice:
private void test()
{
numPages = 100;
badPages = new int[] { 3, 63, 98 };
for (int i = 0; i < numPages; i++)
{
for (int j = 0; j < badPages.Length; j++)
{
if (badPages[j] == i)
{
i++;
}
}
//copiaPagina(i);
}
}
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
Ultima modifica di RaouL_BennetH : 23-06-2010 alle 17:30. |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Jul 2008
Messaggi: 237
|
Il codice che segue richiede solo che tu passi il numero di pagine totali del PDF e una sequenza di pagine da eliminare (nota che il codice considera scontata l'assenza di numeri di pagina da eliminare duplicati. Se questo non fosse il tuo caso basta aggiungere una chiamata a Distinct prima di OrderBy).
Con LINQ gli elementi della sequenza vengono disposti in ordine crescente, poi la sequenza viene trasformata in lista. In questo modo hai la certezza che la pagina in testa alla lista sia la pagina con numero più basso tra quelle da eliminare. Iniziando il processo di copia ti serve semplicemente verificare che la lista di pagine da eliminare non sia vuota e che la pagina in testa alla lista abbia lo stesso numero di quella che stai copiando. Se questo è il caso, invece di copiare la pagina elimini l'elemento in testa alla lista, altrimenti procedi alla copia. L'uso della LinkedList invece che di una qualsiasi list è per minimizzare la complessità algoritmica, la quale in questo caso ha O(1) per l'eliminazione della testa invece dell'O(n) di una List normale. Ecco il codice: Codice:
private void EliminaPagine(int totalePagine, IEnumerable<int> pagineDaEliminare)
{
var badPages = new LinkedList<int>(pagineDaEliminare.OrderBy(numPagina => numPagina));
for(int i = 0; i < totalePagine; i++)
{
if(badPages.Count > 0 && badPages.First == i)
{
//aggiorniamo la lista
badPages.RemoveFirst();
}
else
{
CopiaPagina(i);
}
}
}
Ogni valore negativo impedisce al codice di funzionare, mentre indicare il numero di pagina contanto la prima come pagina 1 causerebbe chiaramente l'eliminazione delle pagine successive a quelle da eliminare effettivamente o, in caso si tentasse di eliminare l'ultima pagina, nessun'eliminazione. Se utilizzi la libreria Code Contracts di Microsoft ti consiglio un'Ensures(badPages.Count == 0) per accertarti che tutte le pagine siano state eliminate. Ultima modifica di !k-0t1c! : 26-06-2010 alle 09:08. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
Ciao
Ho dimenticato di dire che potevo muovermi soltanto in ambito net 2.0 Ad ogni modo, credo di poter riuscire lo stesso a studiare la soluzione da te proposta e magari adattarla al 2.0. In questi giorni comunque sono riuscito nell'intento: L'utente inserisce il numero di pagine da eliminare separate da virgola. Nei limiti delle mie conoscenze attuali, ecco come ho svolto il tutto: Codice:
using System;
using System.Collection.Generics;
using System.IO;
using System.Text;
using System.Text.RegularExpression;
using iTextSharp.text;
using iTextSharp.text.pdf;
public class PdfHelper
{
public static void SkipPages(string source, string destination, List<int> badPages)
{
try
{
PdfReader sourcePdf = new PdfReader(source);
int totalNumberOfPages = sourcePdf.NumberOfPages;
int firstPage = 1;
Document sourceDoc = new Document(sourcePdf.GetPageSizeWithRotation(1));
FileStream stream = new FileStream(destination, FileMode.Create));
PdfWriter destinationPdf = PdfWriter.GetIstance(sourceDoc, stream);
sourceDoc.Open();
PdfContentByte pages = destinationPdf.DirectContent;
for(int i = firstPage; i <= totalNumerOfPages; i++)
{
for(int j = 0; j < badPages.Count; j++)
{
if(badPages[j] == i)
{
i++;
}
}
sourceDoc.SetPageSize(source.GetPageSizeWithRotation(i));
sourceDoc.NewPage();
PdfImportedPage currentPage = destinationPdf.GetImportedPage(source, i);
//blabla code per l'orientamento
}
//blabla
Codice:
//DoSkip()
List<int> badPages = new List<int>();
string[] pagesToSkip = Regex.Split(txtPages.Text, @"\D+");
foreach(string page in pagesToSkip)
{
int pageNumber;
if(int.TryParse(page, out pageNumber))
{
badPages.Add(pageNumber);
}
}
SkipPages(sourceFileName, mySaveDialog.FileName, badPages);
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 17:54.



















