[英]How to obtain pdf byte[] from PdfDocument using itext7?
我很難理解如何從 PdfDocument 獲取內容。 我從以前的問題中了解到,PdfDocument 會刷新內容以優化處理大型文檔。 如果我的 function 返回一個新的 PdfDocument,我如何讓 byte[] 傳遞給我的其他函數?
即使使用 PdfDocument.GetReader() - 我似乎也找不到我要找的東西。
我的用例如下:
總結一下:僅給定一個 PdfDocument,我如何從中獲取/創建一個字節 []?
這是我的代碼:
public async Task<BaseResponse> Handle(ReceiveEmailCommand command, CancellationToken cancellationToken) {
var ms = new MemoryStream(command.attachments.First().Content)
var extractedDocument = pdfService.PreparePdfDocument(ms);
var analyzedDocument = await formsRecognizerService.AnalyzeDocument(extractedDocument);
// Do stuff with the analyzed document...
var response = await FileWebService.AddAnalyzedDocumentToFileSystem(analyzedDocument);
}
function AnalyzeDocument 需要一個 Stream 參數。 我想通過類似的東西
new Stream(extractedDocument.GetReader().Stream)
助手 function 實現如下:
public PdfDocument PreparePdfDocument(MemoryStream ms)
{
PdfDocument extractedDoc;
var pdfReader = new PdfReader(ms);
var pdf = new PdfDocument(pdfReader);
var doc = new Document(pdf);
var matches = GetNumberWithPages(pdf);
if (matches.Count > 0)
{
var pageRange = matches
.Where(x => x.Number == "125")
.Select(x => Convert.ToInt32(x.PageIndex))
.ToList();
extractedDoc = SplitPages(pdf, pageRange.First(), pageRange.Last());
}
else
{
// If we couldn't parse the PDF then just take first 4, 3 or 2 pages
try
{
extractedDoc = SplitPages(pdf, 1, 4);
}
catch (ITextException)
{
try
{
extractedDoc = SplitPages(pdf, 1, 3);
}
catch (ITextException)
{
try
{
extractedDoc = SplitPages(pdf, 1, 2);
}
catch (Exception)
{
throw;
}
}
}
}
return extractedDoc;
}
private static List<Match> GetNumberWithPages(PdfDocument doc)
{
var regex = new Regex(@"\s+([0-9]+)\s+(\([0-9]+\/[0-9]+\))\s+Page\s+([0-9])\s+of\s+([0-9]+)");
var matches = new List<Match>();
for (int i = 1; i <= doc.GetNumberOfPages(); i++)
{
var page = doc.GetPage(i);
var text = PdfTextExtractor.GetTextFromPage(page);
if (!string.IsNullOrEmpty(text))
{
var match = regex.Match(text);
if (match.Success)
{
var match = EvaluateMatch(match, i, doc.GetNumberOfPages());
if (match != null)
{
matches.Add(match);
}
}
}
}
return matches;
}
private static Match? EvaluateMatch(Match match, int pageIndex, int totalPages)
{
if (match.Captures.Count == 1 && match.Groups.Count == 5)
{
var match = new Match
{
Number = match.Groups[1].Value,
Version = match.Groups[2].Value,
PageIndex = pageIndex.ToString(),
TotalPages = totalPages.ToString()
};
return match;
}
else
{
return null;
}
}
public PdfDocument SplitPages(PdfDocument doc, int startIndex, int endIndex)
{
var outputDocument = CreatePdfDocument();
doc.CopyPagesTo(startIndex, endIndex, outputDocument);
return outputDocument;
}
public PdfDocument CreatePdfDocument()
{
var baos = new ByteArrayOutputStream();
var writer = new PdfWriter(baos);
var pdf = new PdfDocument(writer);
return pdf;
}
我很難理解如何從 PdfDocument 獲取內容。
你沒有!
當您創建要寫入的PdfDocument
時,您使用PdfWriter
對其進行初始化。 該PdfWriter
反過來已被初始化為在某處寫入。 如果要訪問最終的 PDF,則必須關閉PdfDocument
並在某處查看。 此外,從PdfWriter
的某個地方檢索它也不容易,因為它被包裹在其中的許多層中。 因此,您應該在附近的某個地方保留對它的引用。
因此,您的ByteArrayOutputStream
通常不會隱藏在某些方法CreatePdfDocument
中,而是在基本方法中創建並作為參數轉發給其他方法。 然后,您最終可以檢索其數據。 如果您需要創建像這樣隱藏的ByteArrayOutputStream
,您可以返回一Pair
PdfDocument
和ByteArrayOutputStream
而不是普通的PdfDocument
。
By the way, the idea behind this architecture is that iText tries to write as much PDF content as possible to that somewhere output as early as possible and free the memory. 這允許它創建大型文檔,而無需類似大量的 memory。
當我返回 stream 時,我無法訪問已關閉的 stream
ByteArrayOutputStream
本質上是一個MemoryStream
; 所以你可以特別調用ToArray
來檢索完成的 PDF 即使它已經關閉。
如果您需要ByteArrayOutputStream
作為常規 stream,只需為您的編寫器調用PdfWriter.SetCloseStream(false)
以防止close
PdfDocument
也關閉 stream。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.