Oggi ho avuto bisogno di trovare un modo per estrarre il contenuto testuale (txt - plain-text) di alcuni file PDF all'interno del codice di un controller MVC di una applicazione Web ASP.NET. Sfortunatamente, non esistono molte librerie open-source che consentono di farlo in modo efficace.
Fortunatamente, dopo un pò di tempo passato a cercare su Google, mi sono imbattuto in una "vecchia amica" - la libreria iTextSharp, che avevo già avuto modo di utilizzare in passato per uno scenario di utilizzo piuttosto diverso ma sempre relativo a file PDF. Recuperando la pagina ufficiale del progetto su SourceForge ho potuto constatare come quella che una volta era una libreria open-source si è oggi evoluta in un vero e proprio prodotto commerciale, distribuito sotto il nome di iText.
La "nuova" versione della libreria, sviluppata per Java ma disponibile anche per .NET grazie a un porting che si chiama ancora iTextSharp, è fortunatamente ancora disponibile in modalità Comunity Edition, una versione gratuita per sviluppatori distribuita su licenza AGPL.
Per farla breve, nel giro di pochi minuti ho installato iTextSharp 5.5.13 da NuGet all'interno del mio progetto e ho utilizzato questa libreria per realizzare questa semplice classe statica che consente di estrarre il contenuto testuale da qualsiasi file PDF:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using iTextSharp.text.pdf; using iTextSharp.text.pdf.parser; namespace PDF { /// <summary> /// Parses a PDF file and extracts the text from it. /// </summary> public static class PDFParser { /// <summary> /// Extracts a text from a PDF file. /// </summary> /// <param name="filePath">the full path to the pdf file.</param> /// <returns>the extracted text</returns> public static string GetText(string filePath) { var sb = new StringBuilder(); try { using (PdfReader reader = new PdfReader(filePath)) { string prevPage = ""; for (int page = 1; page <= reader.NumberOfPages; page++) { ITextExtractionStrategy its = new SimpleTextExtractionStrategy(); var s = PdfTextExtractor.GetTextFromPage(reader, page, its); if (prevPage != s) sb.Append(s); prevPage = s; } reader.Close(); } } catch (Exception e) { throw e; } return sb.ToString(); } } } |
Una volta estratto il plain-text abbiamo varie possibilità, tra cui quella di formattare quest'ultimo in HTML sfruttando i line-breaks - o altre caratteristiche del testo a noi note - in modo piuttosto semplice:
1 2 3 4 5 6 7 8 9 |
public static GetHTMLText(string sourceFilePath) { var txt = PDFParser.GetText(sourceFilePath); var sb = new StringBuilder(); foreach (string s in txt.Split('\n')) { sb.AppendFormat("<p>{0}</p>", s); } return sb.ToString(); } |
Niente male, vero?
Per il momento è tutto: mi auguro che questa semplice classe potrà essere di aiuto agli sviluppatori che si imbatteranno in questo articolo cercando un modo per convertire i loro PDF in formato testo o HTML!