Tôi đang sử dụng iTextSharp để đọc nội dung văn bản từ PDF. Tôi cũng có thể đọc được điều đó. Nhưng tôi đang mất định dạng văn bản như phông chữ, màu sắc vv Có cách nào để có được định dạng đó là tốt.làm thế nào tôi có thể nhận được định dạng văn bản với iTextSharp
Dưới đây là đoạn mã tôi đang sử dụng để văn bản chính xác -
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 e.g. '\\' 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 < input.Length; i++)
{
char c = (char)input[i];
if (inTextObject)
{
// Position the text
if (bracketDepth == 0)
{
if (CheckToken(new string[] { "TD", "Td" }, previousCharacters))
{
resultString += "\n\r";
}
else
{
if (CheckToken(new string[] {"'", "T*", "\""}, previousCharacters))
{
resultString += "\n";
}
else
{
if (CheckToken(new string[] { "Tj" }, previousCharacters))
{
resultString += " ";
}
}
}
}
// End of a text object, also go to a new line.
if (bracketDepth == 0 && CheckToken(new string[]{"ET"}, previousCharacters))
{
inTextObject = false;
resultString += " ";
}
else
{
// Start outputting text
if ((c == '(') && (bracketDepth == 0) && (!nextLiteral))
{
bracketDepth = 1;
}
else
{
// Stop outputting text
if ((c == ')') && (bracketDepth == 1) && (!nextLiteral))
{
bracketDepth = 0;
}
else
{
// Just a normal text character:
if (bracketDepth == 1)
{
// Only print out next character no matter what.
// Do not interpret.
if (c == '\\' && !nextLiteral)
{
nextLiteral = true;
}
else
{
if (((c >= ' ') && (c <= '~')) || ((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;
}
Cảm ơn Chris về giải pháp có giá trị và các liên kết hữu ích của bạn. Tôi sẽ cố gắng thực hiện điều này. – IrfanRaza
Cảm ơn rất nhiều Chris giải pháp của bạn đã giúp chúng tôi rất nhiều, nhưng chúng tôi bị tấn công ở một nơi, làm thế nào chúng ta có thể tìm thấy nếu văn bản là gạch dưới hay không? – Deepesh
Xin chào @Deepesh, rất tiếc, thông số PDF không hỗ trợ gạch dưới ở cấp văn bản thô. Thay vào đó nó được thực hiện theo một trong hai cách, hoặc thông qua chú thích (hiếm) hoặc bằng cách vẽ một hình chữ nhật rất mỏng dưới một số văn bản (phổ biến nhất). Trong cả hai trường hợp, bạn sẽ phải tính toán vị trí của văn bản liên quan đến hình chữ nhật. Trong khi kỹ thuật có thể, tôi nghĩ rằng nó sẽ là một nhức đầu khổng lồ. Tuy nhiên, nếu tài liệu của bạn là thống nhất, bạn có thể viết một số quy tắc tùy ý. –