<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Barrdega Panamá / P4 Software</title>
    <description>The latest articles on DEV Community by Barrdega Panamá / P4 Software (@barrdega).</description>
    <link>https://dev.to/barrdega</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4148395%2Fbaa5c180-28e3-4838-be11-7e6816978089.png</url>
      <title>DEV Community: Barrdega Panamá / P4 Software</title>
      <link>https://dev.to/barrdega</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/barrdega"/>
    <language>en</language>
    <item>
      <title>Writing 100,000-row Excel files in .NET with 27 MB allocated</title>
      <dc:creator>Barrdega Panamá / P4 Software</dc:creator>
      <pubDate>Wed, 14 Oct 2026 11:00:52 +0000</pubDate>
      <link>https://dev.to/barrdega/writing-100000-row-excel-files-in-net-with-27-mb-allocated-1mne</link>
      <guid>https://dev.to/barrdega/writing-100000-row-excel-files-in-net-with-27-mb-allocated-1mne</guid>
      <description>&lt;p&gt;&lt;em&gt;Update, 14 October: the library is now published as **SheetStream.NET&lt;/em&gt;* (&lt;code&gt;dotnet add package SheetStream.NET&lt;/code&gt;); the repository moved to github.com/P4Software/SheetStream.NET. Version 0.4.0 added editing of small workbooks, pivot tables, cached formula results, async reading, Native AOT support and a Roslyn analyzer; the million-row benchmark is in the repo.*&lt;/p&gt;

&lt;p&gt;Most .NET Excel libraries build the whole workbook in memory and save it at the end. That's convenient, and it's why a 100,000-row export can allocate hundreds of megabytes to over a gigabyte. Here's how we built SheetStream to write the same file with about 27 MB allocated, and what that design costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  An .xlsx is a zip of XML
&lt;/h2&gt;

&lt;p&gt;Open any &lt;code&gt;.xlsx&lt;/code&gt; with a zip tool and you'll find &lt;code&gt;xl/worksheets/sheet1.xml&lt;/code&gt;, &lt;code&gt;xl/styles.xml&lt;/code&gt;, &lt;code&gt;xl/sharedStrings.xml&lt;/code&gt; and a few relationship files. The worksheet is a &lt;code&gt;&amp;lt;sheetData&amp;gt;&lt;/code&gt; element full of &lt;code&gt;&amp;lt;row&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;c&amp;gt;&lt;/code&gt; (cell) elements.&lt;/p&gt;

&lt;p&gt;So writing a sheet is just writing XML into a zip entry, and &lt;code&gt;System.IO.Compression&lt;/code&gt; plus &lt;code&gt;XmlWriter&lt;/code&gt; can do that as a stream:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"xl/worksheets/sheet1.xml"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;XmlWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BufferedStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// &amp;lt;worksheet&amp;gt;&amp;lt;sheetData&amp;gt;&amp;lt;row r="1"&amp;gt;&amp;lt;c r="A1" t="s"&amp;gt;&amp;lt;v&amp;gt;0&amp;lt;/v&amp;gt;&amp;lt;/c&amp;gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The catch: Excel's schema is strict about order
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;CT_Worksheet&lt;/code&gt; is an XML Schema &lt;em&gt;sequence&lt;/em&gt;. Column widths (&lt;code&gt;&amp;lt;cols&amp;gt;&lt;/code&gt;) must come before &lt;code&gt;&amp;lt;sheetData&amp;gt;&lt;/code&gt;, and merged cells, conditional formatting, validations, hyperlinks and tables come after it, in a fixed order. Get the order wrong and Excel shows "We found a problem with some content".&lt;/p&gt;

&lt;p&gt;For a streaming writer this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Layout before data.&lt;/strong&gt; Column widths and frozen panes have to be known before the first row. SheetStream throws a clear exception if you set them late.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Everything else at the end.&lt;/strong&gt; Features that live after &lt;code&gt;sheetData&lt;/code&gt; are collected while you write and emitted in schema order when the sheet is sealed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Shared strings and styles live in other parts
&lt;/h2&gt;

&lt;p&gt;Cells don't contain text; they point into &lt;code&gt;sharedStrings.xml&lt;/code&gt;. Styles are indexes into &lt;code&gt;styles.xml&lt;/code&gt;, which itself has five interlocking tables (number formats, fonts, fills, borders, cell formats). Both parts are written last, after every sheet, so the writer keeps two small in-memory dictionaries and nothing else.&lt;/p&gt;

&lt;h2&gt;
  
  
  AutoFit without font metrics or memory
&lt;/h2&gt;

&lt;p&gt;AutoFit needs to see every value before writing &lt;code&gt;&amp;lt;cols&amp;gt;&lt;/code&gt;, which comes first. Our trick: when AutoFit is on, rows spill to a temporary file while their widths are measured, then the header is written and the rows are copied back in 64 KB chunks. Memory stays flat; disk use roughly equals the uncompressed sheet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filling templates without a DOM
&lt;/h2&gt;

&lt;p&gt;Designers want to build the report in Excel. SheetStream streams the template's XML around your rows, continues the template's style and string numbering, stretches tables and conditional formats over the new rows, and drops &lt;code&gt;calcChain.xml&lt;/code&gt; (a stale calculation chain is a classic repair trigger) so Excel recalculates on open.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;100,000 rows × 10 formatted columns, BenchmarkDotNet, .NET 8:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SheetStream (fastest compression)&lt;/td&gt;
&lt;td&gt;534 ms&lt;/td&gt;
&lt;td&gt;27 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MiniExcel&lt;/td&gt;
&lt;td&gt;596 ms&lt;/td&gt;
&lt;td&gt;343 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EPPlus 4.5.3.3&lt;/td&gt;
&lt;td&gt;2,287 ms&lt;/td&gt;
&lt;td&gt;390 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ClosedXML&lt;/td&gt;
&lt;td&gt;3,103 ms&lt;/td&gt;
&lt;td&gt;1,104 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With default (best) compression SheetStream takes 1,013 ms, slower than MiniExcel, in exchange for smaller files. The suite is in the repo if you want to check our work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What streaming costs
&lt;/h2&gt;

&lt;p&gt;No formula engine, no pivot tables, and no "open any workbook, change a cell, save". Rows go in ascending order, one sheet at a time. If you need random access on a small sheet, there's an opt-in &lt;code&gt;Cells[row, col]&lt;/code&gt; mode that buffers just that sheet.&lt;/p&gt;

&lt;p&gt;SheetStream.NET is MIT licensed: &lt;a href="https://github.com/P4Software/SheetStream.NET" rel="noopener noreferrer"&gt;https://github.com/P4Software/SheetStream.NET&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package SheetStream.NET
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>excel</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Let your customers ask Claude about your docs</title>
      <dc:creator>Barrdega Panamá / P4 Software</dc:creator>
      <pubDate>Tue, 29 Sep 2026 03:14:07 +0000</pubDate>
      <link>https://dev.to/barrdega/let-your-customers-ask-claude-about-your-docs-35bd</link>
      <guid>https://dev.to/barrdega/let-your-customers-ask-claude-about-your-docs-35bd</guid>
      <description>&lt;p&gt;Readers usually arrive at your docs with one specific question. They don't want a table of contents; they want the answer.&lt;/p&gt;

&lt;p&gt;So we made every public docs site on &lt;a href="https://opendocs.cloud" rel="noopener noreferrer"&gt;OpenDocs&lt;/a&gt; on a paid plan double as a &lt;strong&gt;read-only MCP server&lt;/strong&gt;. A reader adds one URL to Claude, asks their question, and Claude answers from your published pages, with a link back to the exact page.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Each docs site answers the Model Context Protocol at its own address plus &lt;code&gt;/mcp&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;https://app.opendocs.cloud/docs/{your-org}/mcp&lt;/code&gt;, or&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;https://docs.yourcompany.com/mcp&lt;/code&gt; on a custom domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once connected, Claude gets four read-only tools: list the site's spaces, read a space's table of contents, search the published pages, and read a page as Markdown. Every result carries the page's public URL, so answers link straight back to your site.&lt;/p&gt;

&lt;h2&gt;
  
  
  What readers do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;claude.ai or Claude Desktop:&lt;/strong&gt; Settings &amp;gt; Connectors &amp;gt; Add custom connector, then paste the address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http docs https://docs.yourcompany.com/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No OpenDocs account, no sign-in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's shared (and what isn't)
&lt;/h2&gt;

&lt;p&gt;Only what's already public: published pages in public spaces, read-only. Drafts, unlisted spaces and private spaces are never part of it, however the question is phrased. Each visitor is rate limited.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup for site owners
&lt;/h2&gt;

&lt;p&gt;Nothing to turn on. It's included on the Pro, Enterprise and Compliance plans, and during the 14-day Pro trial. Every public site shows an &lt;strong&gt;Add to Claude&lt;/strong&gt; button in its header with the address and these steps. If you want to keep a space out, switch it off in that space's settings under &lt;strong&gt;Claude&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on a live site
&lt;/h2&gt;

&lt;p&gt;Our own product docs are connected: &lt;code&gt;https://app.opendocs.cloud/docs/p4-software/mcp&lt;/code&gt;. Add it in Claude and ask it something about the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing docs with Claude, too
&lt;/h2&gt;

&lt;p&gt;The other direction works as well: OpenDocs is listed in Claude's connector directory, so you can ask Claude to draft, edit, organize and publish pages in your own workspace, on every plan including Free. Every change it makes is saved in page history.&lt;/p&gt;

&lt;p&gt;More practical guides (publishing from Claude, writing SOPs with it, a prompt library): &lt;a href="https://opendocs.cloud/guides/" rel="noopener noreferrer"&gt;opendocs.cloud/guides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://opendocs.cloud/guides/add-your-docs-to-claude/" rel="noopener noreferrer"&gt;opendocs.cloud&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>claude</category>
      <category>documentation</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
