diff --git a/dotnet/src/MiniExcel.Rust/MiniExcel.Rust.csproj b/dotnet/src/MiniExcel.Rust/MiniExcel.Rust.csproj
index 3201746..3cc1cd4 100644
--- a/dotnet/src/MiniExcel.Rust/MiniExcel.Rust.csproj
+++ b/dotnet/src/MiniExcel.Rust/MiniExcel.Rust.csproj
@@ -29,7 +29,6 @@
-
diff --git a/dotnet/src/MiniExcel.Rust/MiniExcelBinaryPayload.cs b/dotnet/src/MiniExcel.Rust/MiniExcelBinaryPayload.cs
new file mode 100644
index 0000000..90da468
--- /dev/null
+++ b/dotnet/src/MiniExcel.Rust/MiniExcelBinaryPayload.cs
@@ -0,0 +1,339 @@
+using System.Collections;
+using System.Globalization;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace MiniExcelLibs;
+
+internal static class MiniExcelBinaryPayload
+{
+ private const byte Version = 1;
+ private const int MaxDepth = 64;
+
+ private enum PayloadKind : byte
+ {
+ XlsxWrite = 1,
+ CsvWrite = 2,
+ TemplateValue = 3,
+ MappedTemplate = 4
+ }
+
+ private enum ValueKind : byte
+ {
+ Null,
+ Boolean,
+ Int64,
+ UInt64,
+ Double,
+ String,
+ Array,
+ Object,
+ Decimal
+ }
+
+ internal static byte[] EncodeXlsxWrite(
+ IReadOnlyList schema,
+ MiniExcelRustWriteOptions options)
+ {
+ using var stream = CreatePayload(PayloadKind.XlsxWrite, out var writer);
+ using (writer)
+ {
+ WriteStrings(writer, schema);
+ WriteString(writer, options.SheetName);
+ WriteBoolean(writer, options.OverwriteFile);
+ WriteBoolean(writer, options.PrintHeader);
+ WriteBoolean(writer, options.AutoFilter);
+ WriteBoolean(writer, options.RightToLeft);
+ WriteBoolean(writer, options.AutoWidth);
+ WriteBoolean(writer, options.WrapCellContents);
+ writer.Write((byte)options.HorizontalAlignment);
+ writer.Write((byte)options.VerticalAlignment);
+ writer.Write((byte)options.TableStyle);
+ WriteBoolean(writer, options.HeaderWrapText);
+ WriteString(writer, options.HeaderBackgroundColor);
+ writer.Write((byte)options.HeaderHorizontalAlignment);
+ writer.Write((byte)options.HeaderVerticalAlignment);
+ writer.Write(options.MinWidth);
+ writer.Write(options.MaxWidth);
+ writer.Write(options.FreezeRowCount);
+ writer.Write(options.FreezeColumnCount);
+ WriteString(writer, options.DateFormat);
+ WriteString(writer, options.TimeFormat);
+ WriteString(writer, options.DateTimeFormat);
+ WriteString(writer, options.DurationFormat);
+ WriteStringMap(writer, options.ColumnFormats);
+ WriteDoubleMap(writer, options.ColumnWidths);
+ WriteBooleanMap(writer, options.HiddenColumns);
+ WriteStrings(
+ writer,
+ options.DynamicColumns
+ .Where(column => column.Value.IsFormula)
+ .Select(column => string.IsNullOrWhiteSpace(column.Value.Name)
+ ? column.Key
+ : column.Value.Name!)
+ .ToArray());
+ }
+ return stream.ToArray();
+ }
+
+ internal static byte[] EncodeCsvWrite(
+ IReadOnlyList schema,
+ MiniExcelRustCsvWriteOptions options)
+ {
+ using var stream = CreatePayload(PayloadKind.CsvWrite, out var writer);
+ using (writer)
+ {
+ WriteStrings(writer, schema);
+ writer.Write(checked((byte)options.Delimiter));
+ writer.Write((byte)options.Encoding);
+ WriteBoolean(writer, options.WriteBom);
+ WriteBoolean(writer, options.PrintHeader);
+ WriteBoolean(writer, options.OverwriteFile);
+ }
+ return stream.ToArray();
+ }
+
+ internal static byte[] EncodeTemplateValue(object? value)
+ {
+ using var stream = CreatePayload(PayloadKind.TemplateValue, out var writer);
+ using (writer)
+ WriteValue(writer, value, 0, new HashSet