title: Blazor WASM Load and display large pdfs by splitting them as streams
body: <p>I'm working on a Blazor WASM App and I want my users to easily open pdf files on specific pages that contain additional information.
  I cannot distribute those files myself or upload them to any kind of server. Each user has to provide them themselves.</p>
  <p>Because the files are up to 60MB big I cannot convert the uploaded file to base64 and display them as described <a href="https://stackoverflow.com/a/17562800/14606084">here</a>.</p>
  <p>However I don't have to display the whole file and could just load the needed page +- some pages around them.</p>
  <p>For that I tried using iText7 <code>ExtractPageRange()</code>. <a href="https://stackoverflow.com/a/46377309/14606084">This</a> answer indicates, that I have to override the <code>GetNextPdfWriter()</code> Method and to store all streams in an collection.</p>
  <pre><code>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&lt;MemoryStream&gt; UsedStreams { get; set; } = new List&lt;MemoryStream&gt;();
  </code></pre>
  <p>Then I thought I could merge those streams and convert them to base64</p>
  <pre><code>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 = &quot;data:application/pdf;base64,&quot;;
          currentPdfContent += Convert.ToBase64String(data);
          pdfLoaded = true;
      }
  </code></pre>
  <p>This however doesn't work.
  Has anyone a suggestion how to get this working? Or maybe a simpler solution I could try.</p>
  <hr />
  <p>Edit:</p>
  <p>I took a closer look in debug and it seems like, the resulting stream <code>outputMs</code> is always empty. So it is probably a problem in how I split the pdf.</p>