我正在開發 Blazor WASM 應用程式,我希望我的用戶能夠輕松地在包含附加資訊的特定頁面上打開 pdf 檔案。我不能自己分發這些檔案或將它們上傳到任何型別的服務器。每個用戶都必須自己提供。
由于檔案最大為 60MB,我無法將上傳的檔案轉換為 base64 并按照此處所述顯示它們。
但是,我不必顯示整個檔案,只需加載所需的頁面 - 它們周圍的一些頁面。
為此,我嘗試使用 iText7 ExtractPageRange()。這個答案表明,我必須重寫GetNextPdfWriter()方法并將所有流存盤在一個集合中。
class ByteArrayPdfSplitter : PdfSplitter {
public ByteArrayPdfSplitter(PdfDocument pdfDocument) : base(pdfDocument) {
}
protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange) {
CurrentMemoryStream = new MemoryStream();
UsedStreams.Add(CurrentMemoryStream);
return new PdfWriter(CurrentMemoryStream);
}
public MemoryStream CurrentMemoryStream { get; private set; }
public List<MemoryStream> UsedStreams { get; set; } = new List<MemoryStream>();
然后我想我可以合并這些流并將它們轉換為base64
var file = loadedFiles.First();
using (MemoryStream ms = new MemoryStream())
{
var rs = file.OpenReadStream(maxFileSize);
await rs.CopyToAsync(ms);
ms.Position = 0;
//rs needed to be converted to ms, because the PdfReader constructer uses a
//synchronious read that isn't supported by rs and throws an exception.
PdfReader pdfReader = new PdfReader(ms);
var document = new PdfDocument(pdfReader);
var splitter = new ByteArrayPdfSplitter(document);
var range = new PageRange();
range.AddPageSequence(1, 10);
var splitDoc = splitter.ExtractPageRange(range);
//Edit commented this out, shouldn't have been here at all leads to an exception
//splitDoc.Close();
var outputMs = new MemoryStream();
foreach (var usedMs in splitter.UsedStreams)
{
usedMs.Position = 0;
outputMs.Position = outputMs.Length;
await usedMs.CopyToAsync(outputMs);
}
var data = outputMs.ToArray();
currentPdfContent = "data:application/pdf;base64,";
currentPdfContent = Convert.ToBase64String(data);
pdfLoaded = true;
}
然而這不起作用。有沒有人建議如何讓它作業?或者也許我可以嘗試一個更簡單的解決方案。
編輯:
我仔細查看了除錯,結果流似乎outputMs總是空的。所以這可能是我如何拆分pdf的問題。
uj5u.com熱心網友回復:
在至少部分清除了我對無法從 blazor WASM 訪問檔案系統意味著什么的誤解之后,我設法找到了一個可行的解決方案。
await using MemoryStream ms = new MemoryStream();
var rs = file.OpenReadStream(maxFileSize);
await using var fs = new FileStream("test.pdf", FileMode.Create)
fs.Position = 0;
await rs.CopyToAsync(fs);
fs.Close();
string path = "test.pdf";
string range = "10 - 15";
var pdfDocument = new PdfDocument(new PdfReader("test.pdf"));
var split = new MySplitter(pdfDocument);
var result = split.ExtractPageRange(new PageRange(range));
result.Close();
await using var splitFs = new FileStream("split.pdf", FileMode.Open))
await splitFs.CopyToAsync(ms);
var data = ms.ToArray();
var pdfContent = "data:application/pdf;base64,";
pdfContent = System.Convert.ToBase64String(data);
Console.WriteLine(pdfContent);
currentPdfContent = pdfContent;
使用此答案中的 MySplitter 類。
class MySplitter : PdfSplitter
{
public MySplitter(PdfDocument pdfDocument) : base(pdfDocument)
{
}
protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange)
{
String toFile = "split.pdf";
return new PdfWriter(toFile);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/475920.html
標籤:C# pdf 文本 blazor-webassembly
下一篇:Flutter錯誤:無法在“WidgetsBinding”上呼叫方法“addPostFrameCallback”?因為它可能為空
