Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CreatePdf.NET/CreatePdf.NET.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<PackageId>CreatePdf.NET</PackageId>
<Title>CreatePdf.NET - Simple PDF Creation Library</Title>
<Version>3.0.4</Version>
<Version>3.0.5</Version>
<Authors>Alexander Nachtmann</Authors>
<Summary>Lightweight PDF generation library for .NET 10/9/8 with text rendering, bitmap graphics, and OCR</Summary>
<Description>CreatePdf.NET is a simple, fast PDF creation library for .NET applications. Generate PDF documents with text rendering, bitmap graphics, and optional OCR text extraction. Lightweight, dependency-free, 100% test coverage. Perfect for creating reports, invoices, receipts, labels, and documents. Supports .NET 10, .NET 9, and .NET 8 with fluent C# API.</Description>
Expand Down
30 changes: 23 additions & 7 deletions CreatePdf.NET/Document.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,21 +202,37 @@ public async Task SaveAndShowDirectoryAsync(string? filename = null)
}

/// <summary>
/// Saves the document to a PDF file.
/// Renders the document to an in-memory PDF and returns its bytes, without touching the disk.
/// </summary>
/// <param name="filename">Optional filename. If not provided, generates a timestamped name.</param>
/// <returns>The full path to the saved PDF file.</returns>
public async Task<string> SaveAsync(string? filename = null)
/// <returns>The complete PDF document as a byte array.</returns>
/// <example>
/// <code>
/// byte[] pdf = await Pdf.Create(Dye.White)
/// .AddText("Hello World")
/// .ToBytesAsync();
/// </code>
/// </example>
public async Task<byte[]> ToBytesAsync()
{
var path = FileOperations.GetOutputPath(filename);

await using var stream = File.Create(path);
await using var stream = new MemoryStream();
await using var writer = new PdfWriter(stream, _background);

foreach (var content in _contents)
content.Render(writer);

await writer.FinalizeAsync();
return stream.ToArray();
}

/// <summary>
/// Saves the document to a PDF file.
/// </summary>
/// <param name="filename">Optional filename. If not provided, generates a timestamped name.</param>
/// <returns>The full path to the saved PDF file.</returns>
public async Task<string> SaveAsync(string? filename = null)
{
var path = FileOperations.GetOutputPath(filename);
await File.WriteAllBytesAsync(path, await ToBytesAsync());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep SaveAsync streaming to the file

For large bitmap-heavy documents, routing SaveAsync through ToBytesAsync substantially raises peak memory: PdfWriter already buffers the whole PDF internally, then ToBytesAsync copies it into a MemoryStream and ToArray() before the file write starts. A document with long AddPixelText content can therefore require multiple full-size copies of the PDF where the previous File.Create(path) path only copied the writer buffer directly to disk. Keeping SaveAsync on the file-stream writer path (or factoring a shared render-to-stream helper) avoids making normal file saves fail with OOM in cases that previously completed.

Useful? React with 👍 / 👎.

return path;
}
Comment on lines +232 to 237

Expand Down
Loading