Como posso obter formatação de texto com iTextSharp

Eu estou usando iTextSharp para ler o conteúdo do texto de PDF. Eu sou capaz de ler isso também. Mas estou perdendo a formatação de texto como a fonte, cor etc. Existe alguma maneira de obter essa formatação também.

Abaixo está o segmento de código que estou usando para o texto exato –

PdfReader reader = new PdfReader("F:\\EBooks\\AspectsOfAjax.pdf"); textBox1.Text = ExtractTextFromPDFBytes(reader.GetPageContent(1)); private string ExtractTextFromPDFBytes(byte[] input) { if (input == null || input.Length == 0) return ""; try { string resultString = ""; // Flag showing if we are we currently inside a text object bool inTextObject = false; // Flag showing if the next character is literal eg '\\' to get a '\' character or '\(' to get '(' bool nextLiteral = false; // () Bracket nesting level. Text appears inside () int bracketDepth = 0; // Keep previous chars to get extract numbers etc.: char[] previousCharacters = new char[_numberOfCharsToKeep]; for (int j = 0; j < _numberOfCharsToKeep; j++) previousCharacters[j] = ' '; for (int i = 0; i = ' ') && (c = 128) && (c < 255))) { resultString += c.ToString(); } nextLiteral = false; } } } } } } // Store the recent characters for when we have to go back for a checking for (int j = 0; j < _numberOfCharsToKeep - 1; j++) { previousCharacters[j] = previousCharacters[j + 1]; } previousCharacters[_numberOfCharsToKeep - 1] = c; // Start of a text object if (!inTextObject && CheckToken(new string[]{"BT"}, previousCharacters)) { inTextObject = true; } } return resultString; } catch { return ""; } } private bool CheckToken(string[] tokens, char[] recent) { foreach(string token in tokens) { if ((recent[_numberOfCharsToKeep - 3] == token[0]) && (recent[_numberOfCharsToKeep - 2] == token[1]) && ((recent[_numberOfCharsToKeep - 1] == ' ') || (recent[_numberOfCharsToKeep - 1] == 0x0d) || (recent[_numberOfCharsToKeep - 1] == 0x0a)) && ((recent[_numberOfCharsToKeep - 4] == ' ') || (recent[_numberOfCharsToKeep - 4] == 0x0d) || (recent[_numberOfCharsToKeep - 4] == 0x0a)) ) { return true; } } return false; } 

Deixe-me tentar apontar você em uma direção diferente. iTextSharp tem um sistema de extração de texto muito bonito e simples que manipula alguns dos tokens básicos. Infelizmente, ele não lida com informações de colors, mas, de acordo com o @Mark Storer, pode não ser muito difícil de implementar .

COMEÇAR EDIT

Comecei a trabalhar na implementação de informações sobre colors. Veja meu post aqui para mais detalhes. (Desculpe pela má formatação, saindo para jantar agora.)

END EDIT

O código abaixo combina várias perguntas e respostas aqui, incluindo esta para obter a altura da fonte (embora não seja exata), bem como outra (que para a vida de mim não consigo encontrar mais) que mostra como detectar faux negrito.

O PostscriptFontName retorna alguns caracteres adicionais na frente do nome da fonte, acho que tem a ver com quando você incorpora subconjuntos de fonts.

Abaixo está um aplicativo WinForms completo que tem como alvo o iTextSharp 5.1.1.0 e extrai o texto como HTML.

Captura de canvas do PDF de amostra

Captura de tela do PDF de amostra

Texto de amostra extraído como HTML

 Hello  w o rl d  
Test

Código

 using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using iTextSharp.text.pdf.parser; using iTextSharp.text.pdf; namespace WindowsFormsApplication2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { PdfReader reader = new PdfReader(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Document.pdf")); TextWithFontExtractionStategy S = new TextWithFontExtractionStategy(); string F = iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, 1, S); Console.WriteLine(F); this.Close(); } public class TextWithFontExtractionStategy : iTextSharp.text.pdf.parser.ITextExtractionStrategy { //HTML buffer private StringBuilder result = new StringBuilder(); //Store last used properties private Vector lastBaseLine; private string lastFont; private float lastFontSize; //http://api.itextpdf.com/itext/com/itextpdf/text/pdf/parser/TextRenderInfo.html private enum TextRenderMode { FillText = 0, StrokeText = 1, FillThenStrokeText = 2, Invisible = 3, FillTextAndAddToPathForClipping = 4, StrokeTextAndAddToPathForClipping = 5, FillThenStrokeTextAndAddToPathForClipping = 6, AddTextToPaddForClipping = 7 } public void RenderText(iTextSharp.text.pdf.parser.TextRenderInfo renderInfo) { string curFont = renderInfo.GetFont().PostscriptFontName; //Check if faux bold is used if ((renderInfo.GetTextRenderMode() == (int)TextRenderMode.FillThenStrokeText)) { curFont += "-Bold"; } //This code assumes that if the baseline changes then we're on a newline Vector curBaseline = renderInfo.GetBaseline().GetStartPoint(); Vector topRight = renderInfo.GetAscentLine().GetEndPoint(); iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(curBaseline[Vector.I1], curBaseline[Vector.I2], topRight[Vector.I1], topRight[Vector.I2]); Single curFontSize = rect.Height; //See if something has changed, either the baseline, the font or the font size if ((this.lastBaseLine == null) || (curBaseline[Vector.I2] != lastBaseLine[Vector.I2]) || (curFontSize != lastFontSize) || (curFont != lastFont)) { //if we've put down at least one span tag close it if ((this.lastBaseLine != null)) { this.result.AppendLine(""); } //If the baseline has changed then insert a line break if ((this.lastBaseLine != null) && curBaseline[Vector.I2] != lastBaseLine[Vector.I2]) { this.result.AppendLine("
"); } //Create an HTML tag with appropriate styles this.result.AppendFormat("", curFont, curFontSize); } //Append the current text this.result.Append(renderInfo.GetText()); //Set currently used properties this.lastBaseLine = curBaseline; this.lastFontSize = curFontSize; this.lastFont = curFont; } public string GetResultantText() { //If we wrote anything then we'll always have a missing closing tag so close it here if (result.Length > 0) { result.Append(""); } return result.ToString(); } //Not needed public void BeginTextBlock() { } public void EndTextBlock() { } public void RenderImage(ImageRenderInfo renderInfo) { } } } }