[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"consumer-news-detail-840":3,"consumer-news-interaction-840":38,"consumer-news-related-840":41},{"detail":4,"item":34},{"card":5,"schemaVersion":21,"fields":22,"content":28},{"id":6,"kind":7,"targetType":8,"targetId":9,"subtype":7,"typeLabel":10,"title":11,"subtitle":12,"summary":13,"coverUrl":14,"badgeText":14,"href":15,"sourceName":12,"meta":16,"metrics":18,"tags":19,"resolved":20},"NEWS_ARTICLE:840","news","NEWS_ARTICLE",840,"资讯","MiniPdf Office 转 PDF 支持 Rust 原生实现：3 MB 单文件部署、低内存","博客园","MiniPdf Office 转 PDF 支持 Rust 原生实现：3 MB 单文件部署、低内存 github link : https:\u002F\u002Fgithub.com\u002Fmini-software\u002FMiniPdf 有时候只想在 API、定时任务或 Container 里，把一份 Excel、Word 转成","","\u002Fnews\u002F840",[17],"2026",{},[],true,"consumer-content-detail-v1",{"sourceName":12,"authorName":23,"summary":13,"description":13,"publishTime":24,"updateTime":25,"sourceUrl":26,"language":27},"阿翰","2026-09-02T12:05","2026-09-02T20:37:48","https:\u002F\u002Fwww.cnblogs.com\u002FITWeiHan\u002Fp\u002F22805841\u002Fminipdfrust","中文",{"format":29,"policy":30,"normalized":20,"html":31,"text":32,"wordCount":33,"hasBody":20},"HTML","NEWS_CONTENT_V1","MiniPdf Office 转 PDF 支持 Rust 原生实现：3 MB 单文件部署、低内存\n\u003Cp>github link : \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmini-software\u002FMiniPdf\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">https:\u002F\u002Fgithub.com\u002Fmini-software\u002FMiniPdf\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>有时候只想在 API、定时任务或 Container 里，把一份 Excel、Word 转成 PDF，最后却先安装了一整套 Office、LibreOffice，甚至还要处理 COM 权限、后台进程与 Runtime 版本。\u003C\u002Fp>\n\u003Cp>这类方案不是不能用，而是部署一多，维护成本就会慢慢浮现：镜像文件变大、启动时间拉长、内存难以预估，转换进程卡住时还得处理残留的外部 Process。\u003C\u002Fp>\n\u003Cp>MiniPdf 现在支持 Rust 原生实现，提供 \u003Ccode>minipdf\u003C\u002Fcode> crate 与 \u003Ccode>minipdf-cli\u003C\u002Fcode>。可以直接在 Rust 进程内解析 Office Open XML、排版并生成 PDF。\u003C\u002Fp>\n\u003Ch2>1. 先用 Rust 把 DOCX 转成 PDF\u003C\u002Fh2>\n\u003Cp>先添加 \u003Ccode>minipdf\u003C\u002Fcode>：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>cargo add minipdf\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>接着只需要一个方法：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>fn main() -&gt; minipdf::Result&lt;()&gt; {\n\tminipdf::convert_to_pdf(\"report.docx\", \"report.pdf\")?;\n\tOk(())\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>如果需要直接把 PDF 返回给 Web API，不想先保存为临时文件，也可以取得 \u003Ccode>Vec&lt;u8&gt;\u003C\u002Fcode>：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>let pdf_bytes = minipdf::convert_to_pdf_bytes(\"report.docx\")?;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>输入原本就在内存中时，可以使用 \u003Ccode>convert_bytes_to_pdf\u003C\u002Fcode>，省去自行创建临时 Office 文件的流程：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>let office_bytes = std::fs::read(\"data.xlsx\")?;\nlet pdf_bytes = minipdf::convert_bytes_to_pdf(&amp;office_bytes)?;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>CLI 的使用方式：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>cargo install minipdf-cli\nminipdf report.docx -o report.pdf\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>目前 Rust 版本支持 \u003Ccode>XLSX\u003C\u002Fcode>、\u003Ccode>DOCX\u003C\u002Fcode>，输出为 PDF 1.4；\u003Ccode>PPTX\u003C\u002Fcode> 尚未支持，而且官方仍将它标记为 experimental。如果项目需要 PowerPoint 或更广泛的 Office 兼容性，现阶段仍应使用 MiniPdf 的 .NET 实现。\u003C\u002Fp>\n\u003Ch2>2. Rust 底层原理\u003C\u002Fh2>\n\u003Cp>MiniPdf 的 Rust workspace 很简单，公共 API 位于 \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmini-software\u002FMiniPdf\u002Fblob\u002Fmain\u002Fminipdf-rs\u002Fcrates\u002Fminipdf\u002Fsrc\u002Flib.rs\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">\u003Ccode>crates\u002Fminipdf\u002Fsrc\u002Flib.rs\u003C\u002Fcode>\u003C\u002Fa>。从 \u003Ccode>convert_to_pdf\u003C\u002Fcode> 往下追，可以整理成以下流程：\u003C\u002Fp>\n\u003Col>\n \u003Cli>\u003Ccode>convert_to_pdf\u003C\u002Fcode> 创建默认的 \u003Ccode>ConversionOptions\u003C\u002Fcode>。\u003C\u002Fli>\n \u003Cli>\u003Ccode>convert_to_pdf_with_options\u003C\u002Fcode> 调用 \u003Ccode>convert_to_pdf_bytes_with_options\u003C\u002Fcode>。\u003C\u002Fli>\n \u003Cli>使用 \u003Ccode>fs::read\u003C\u002Fcode> 将 Office 文件读入 \u003Ccode>Vec&lt;u8&gt;\u003C\u002Fcode>。\u003C\u002Fli>\n \u003Cli>优先根据扩展名分派到 \u003Ccode>convert_docx_bytes\u003C\u002Fcode> 或 \u003Ccode>convert_xlsx_bytes\u003C\u002Fcode>。\u003C\u002Fli>\n \u003Cli>没有可识别的扩展名时，再打开 ZIP package，从 \u003Ccode>word\u002F\u003C\u002Fcode>、\u003Ccode>xl\u002F\u003C\u002Fcode> 路径判断格式。\u003C\u002Fli>\n \u003Cli>解析 XML、样式、图片与页面设置，创建内部文档结构。\u003C\u002Fli>\n \u003Cli>将文字、线条、矩形与图片转换成 \u003Ccode>PdfOp\u003C\u002Fcode>，最后由 \u003Ccode>PdfDocument::to_bytes\u003C\u002Fcode> 写出 PDF objects、xref 与 trailer。\u003C\u002Fli>\n \u003Cli>返回最外层后，才使用 \u003Ccode>fs::write\u003C\u002Fcode> 写入输出文件。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>源代码重点部分可以简化成：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pub fn convert_to_pdf_with_options(\n\tinput_path: impl AsRef&lt;Path&gt;,\n\toutput_path: impl AsRef&lt;Path&gt;,\n\toptions: &amp;ConversionOptions,\n) -&gt; Result&lt;()&gt; {\n\tlet pdf = convert_to_pdf_bytes_with_options(input_path, options)?;\n\tfs::write(output_path, pdf)?;\n\tOk(())\n}\n\npub fn convert_bytes_to_pdf_with_options(\n\tinput: &amp;[u8],\n\toptions: &amp;ConversionOptions,\n) -&gt; Result&lt;Vec&lt;u8&gt;&gt; {\n\tmatch detect_office_format(input)? {\n\t\tOfficeFormat::Docx =&gt; docx::convert_docx_bytes(input, options),\n\t\tOfficeFormat::Xlsx =&gt; xlsx::convert_xlsx_bytes(input, options),\n\t\tOfficeFormat::Unknown =&gt; Err(MiniPdfError::UnsupportedFormat),\n\t}\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>接着来看 XLSX。Office Open XML 本身就是 ZIP package，Rust 版本使用 \u003Ccode>zip\u003C\u002Fcode> 打开封装，再通过 \u003Ccode>roxmltree\u003C\u002Fcode> 读取 shared strings、styles、worksheet、print area、图片与分页信息。相关逻辑集中在 \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmini-software\u002FMiniPdf\u002Fblob\u002Fmain\u002Fminipdf-rs\u002Fcrates\u002Fminipdf\u002Fsrc\u002Fxlsx.rs\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">\u003Ccode>xlsx.rs\u003C\u002Fcode>\u003C\u002Fa>。\u003C\u002Fp>\n\u003Cp>DOCX 的处理路径也很接近。它会解析 \u003Ccode>word\u002Fdocument.xml\u003C\u002Fcode>、\u003Ccode>word\u002Fstyles.xml\u003C\u002Fcode> 与 relationships，转换成 paragraph、table、image、page break 等 \u003Ccode>DocxBlock\u003C\u002Fcode>，主要逻辑位于 \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmini-software\u002FMiniPdf\u002Fblob\u002Fmain\u002Fminipdf-rs\u002Fcrates\u002Fminipdf\u002Fsrc\u002Fdocx.rs\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">\u003Ccode>docx.rs\u003C\u002Fcode>\u003C\u002Fa>。\u003C\u002Fp>\n\u003Cp>最后的 PDF 不是交给 Office 或浏览器打印，而是由 \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fmini-software\u002FMiniPdf\u002Fblob\u002Fmain\u002Fminipdf-rs\u002Fcrates\u002Fminipdf\u002Fsrc\u002Fpdf.rs\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">\u003Ccode>pdf.rs\u003C\u002Fcode>\u003C\u002Fa> 自行创建 PDF 1.4 结构。PNG 图像数据使用 Flate 压缩，JPEG 可以保留 DCT 数据，实际用到的字体 glyph 也会通过 \u003Ccode>subsetter\u003C\u002Fcode> 创建 subset，避免把整个字体全部放进 PDF。\u003C\u002Fp>\n\u003Ch2>3. “无特殊依赖”不等于完全没有依赖\u003C\u002Fh2>\n\u003Cp>Rust MiniPdf 在运行转换时，不需要安装：\u003C\u002Fp>\n\u003Col>\n \u003Cli>Microsoft Office\u003C\u002Fli>\n \u003Cli>LibreOffice\u003C\u002Fli>\n \u003Cli>Adobe Acrobat\u003C\u002Fli>\n \u003Cli>.NET Runtime\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>也不需要启动上述应用程序的外部 Process。对于 Container、CI runner、Serverless Job 或权限受限的主机来说，这会让部署与故障排查简单很多。\u003C\u002Fp>\n\u003Cp>但它并不是“零依赖”。编译阶段仍会使用 \u003Ccode>zip\u003C\u002Fcode>、\u003Ccode>roxmltree\u003C\u002Fcode>、\u003Ccode>flate2\u003C\u002Fcode>、\u003Ccode>image\u003C\u002Fcode>、\u003Ccode>rustybuzz\u003C\u002Fcode>、\u003Ccode>ttf-parser\u003C\u002Fcode>、\u003Ccode>subsetter\u003C\u002Fcode> 等 Rust crates，只是这些代码会一起编译进原生可执行文件，不需要在目标主机上另外安装对应的 Runtime。\u003C\u002Fp>\n\u003Cp>有两个实际边界需要注意：\u003C\u002Fp>\n\u003Col>\n \u003Cli>从 crate 自行构建需要 Rust 1.82 以上。\u003C\u002Fli>\n \u003Cli>英文可以使用 PDF 内置的 Helvetica；中文、日文、韩文等 Unicode 内容仍需要可用字体。可以让 CLI 查找系统 fallback fonts，也可以用 \u003Ccode>--fonts\u003C\u002Fcode> 指定自己的字体目录。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>例如在生产环境中，可以只携带项目需要使用的字体：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>minipdf report.docx --fonts .\u002Ffonts -o report.pdf\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>4. 轻量化：Rust CLI 只有 3.35 MiB\u003C\u002Fh2>\n\u003Cp>先比较目前 repository 内已经构建完成的 Windows x64 release binary：\u003C\u002Fp>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>实现\u003C\u002Fth>\n   \u003Cth>可执行文件大小\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>Rust \u003Ccode>minipdf.exe\u003C\u002Fcode>\u003C\u002Ftd>\n   \u003Ctd>3,511,808 bytes（3.35 MiB）\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>.NET Native AOT \u003Ccode>MiniPdf.Cli.exe\u003C\u002Fcode>\u003C\u002Ftd>\n   \u003Ctd>10,674,688 bytes（10.18 MiB）\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>Rust CLI 大约是 .NET Native AOT CLI 的三分之一。\u003C\u002Fp>\n\u003Ch2>5. 实际环境测试\u003C\u002Fh2>\n\u003Cp>本次测试环境如下：\u003C\u002Fp>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>项目\u003C\u002Fth>\n   \u003Cth>环境\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>OS\u003C\u002Ftd>\n   \u003Ctd>Windows 10 Pro 10.0.19045\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>CPU\u003C\u002Ftd>\n   \u003Ctd>AMD Ryzen 5 5600X\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>Rust toolchain\u003C\u002Ftd>\n   \u003Ctd>\u003Ccode>cargo 1.96.0\u003C\u002Fcode>、\u003Ccode>rustc 1.96.0\u003C\u002Fcode>\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>.NET SDK\u003C\u002Ftd>\n   \u003Ctd>10.0.103\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>测试文件\u003C\u002Ftd>\n   \u003Ctd>\u003Ccode>Business expenses budget2.xlsx\u003C\u002Fcode>\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>输入大小\u003C\u002Ftd>\n   \u003Ctd>125,082 bytes\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>测试方式是让 Rust release CLI 与 .NET Native AOT CLI 转换同一份 XLSX，先预热一次，再分别启动五个独立 Process。每次验证 exit code、输出文件存在，而且 PDF header 是 \u003Ccode>%PDF-1.4\u003C\u002Fcode>；时间取五次中位数，Peak Working Set 则在 Process 存活期间采样。\u003C\u002Fp>\n\u003Cp>第一组测试让两边都传入空的 \u003Ccode>--fonts\u003C\u002Fcode> 目录，避免系统字体扫描影响结果：\u003C\u002Fp>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>实现\u003C\u002Fth>\n   \u003Cth>时间中位数\u003C\u002Fth>\n   \u003Cth>Peak Working Set 中位数\u003C\u002Fth>\n   \u003Cth>PDF 大小\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>Rust\u003C\u002Ftd>\n   \u003Ctd>105.66 ms\u003C\u002Ftd>\n   \u003Ctd>15.72 MiB\u003C\u002Ftd>\n   \u003Ctd>464,432 bytes\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>.NET Native AOT\u003C\u002Ftd>\n   \u003Ctd>632.99 ms\u003C\u002Ftd>\n   \u003Ctd>972.99 MiB\u003C\u002Ftd>\n   \u003Ctd>641,314 bytes\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>在这个案例中，Rust 约为 6 倍快，峰值 Working Set 也低很多。可以发现，Rust 原生引擎在不处理额外字体加载时，进程启动与转换路径相当精简。\u003C\u002Fp>\n\u003Cp>但空字体目录不适合直接作为生产环境建议，因为缺少字体时，Unicode 文字的显示结果可能不同。这组数据主要用于隔离字体扫描成本。\u003C\u002Fp>","MiniPdf Office 转 PDF 支持 Rust 原生实现：3 MB 单文件部署、低内存 github link : https:\u002F\u002Fgithub.com\u002Fmini-software\u002FMiniPdf 有时候只想在 API、定时任务或 Container 里，把一份 Excel、Word 转成 PDF，最后却先安装了一整套 Office、LibreOffice，甚至还要处理 COM 权限、后台进程与 Runtime 版本。 这类方案不是不能用，而是部署一多，维护成本就会慢慢浮现：镜像文件变大、启动时间拉长、内存难以预估，转换进程卡住时还得处理残留的外部 Process。 MiniPdf 现在支持 Rust 原生实现，提供 minipdf crate 与 minipdf-cli。可以直接在 Rust 进程内解析 Office Open XML、排版并生成 PDF。 1. 先用 Rust 把 DOCX 转成 PDF 先添加 minipdf： cargo add minipdf 接着只需要一个方法： fn main() -> minipdf::Result\u003C()> { minipdf::convert_to_pdf(\"report.docx\", \"report.pdf\")?; Ok(()) } 如果需要直接把 PDF 返回给 Web API，不想先保存为临时文件，也可以取得 Vec\u003Cu8>： let pdf_bytes = minipdf::convert_to_pdf_bytes(\"report.docx\")?; 输入原本就在内存中时，可以使用 convert_bytes_to_pdf，省去自行创建临时 Office 文件的流程： let office_bytes = std::fs::read(\"data.xlsx\")?; let pdf_bytes = minipdf::convert_bytes_to_pdf(&office_bytes)?; CLI 的使用方式： cargo install minipdf-cli minipdf report.docx -o report.pdf 目前 Rust 版本支持 XLSX、DOCX，输出为 PDF 1.4；PPTX 尚未支持，而且官方仍将它标记为 experimental。如果项目需要 PowerPoint 或更广泛的 Office 兼容性，现阶段仍应使用 MiniPdf 的 .NET 实现。 2. Rust 底层原理 MiniPdf 的 Rust workspace 很简单，公共 API 位于 crates\u002Fminipdf\u002Fsrc\u002Flib.rs。从 convert_to_pdf 往下追，可以整理成以下流程： convert_to_pdf 创建默认的 ConversionOptions。 convert_to_pdf_with_options 调用 convert_to_pdf_bytes_with_options。 使用 fs::read 将 Office 文件读入 Vec\u003Cu8>。 优先根据扩展名分派到 convert_docx_bytes 或 convert_xlsx_bytes。 没有可识别的扩展名时，再打开 ZIP package，从 word\u002F、xl\u002F 路径判断格式。 解析 XML、样式、图片与页面设置，创建内部文档结构。 将文字、线条、矩形与图片转换成 PdfOp，最后由 PdfDocument::to_bytes 写出 PDF objects、xref 与 trailer。 返回最外层后，才使用 fs::write 写入输出文件。 源代码重点部分可以简化成： pub fn convert_to_pdf_with_options( input_path: impl AsRef\u003CPath>, output_path: impl AsRef\u003CPath>, options: &ConversionOptions, ) -> Result\u003C()> { let pdf = convert_to_pdf_bytes_with_options(input_path, options)?; fs::write(output_path, pdf)?; Ok(()) } pub fn convert_bytes_to_pdf_with_options( input: &[u8], options: &ConversionOptions, ) -> Result\u003CVec\u003Cu8>> { match detect_office_format(input)? { OfficeFormat::Docx => docx::convert_docx_bytes(input, options), OfficeFormat::Xlsx => xlsx::convert_xlsx_bytes(input, options), OfficeFormat::Unknown => Err(MiniPdfError::UnsupportedFormat), } } 接着来看 XLSX。Office Open XML 本身就是 ZIP package，Rust 版本使用 zip 打开封装，再通过 roxmltree 读取 shared strings、styles、worksheet、print area、图片与分页信息。相关逻辑集中在 xlsx.rs。 DOCX 的处理路径也很接近。它会解析 word\u002Fdocument.xml、word\u002Fstyles.xml 与 relationships，转换成 paragraph、table、image、page break 等 DocxBlock，主要逻辑位于 docx.rs。 最后的 PDF 不是交给 Office 或浏览器打印，而是由 pdf.rs 自行创建 PDF 1.4 结构。PNG 图像数据使用 Flate 压缩，JPEG 可以保留 DCT 数据，实际用到的字体 glyph 也会通过 subsetter 创建 subset，避免把整个字体全部放进 PDF。 3. “无特殊依赖”不等于完全没有依赖 Rust MiniPdf 在运行转换时，不需要安装： Microsoft Office LibreOffice Adobe Acrobat .NET Runtime 也不需要启动上述应用程序的外部 Process。对于 Container、CI runner、Serverless Job 或权限受限的主机来说，这会让部署与故障排查简单很多。 但它并不是“零依赖”。编译阶段仍会使用 zip、roxmltree、flate2、image、rustybuzz、ttf-parser、subsetter 等 Rust crates，只是这些代码会一起编译进原生可执行文件，不需要在目标主机上另外安装对应的 Runtime。 有两个实际边界需要注意： 从 crate 自行构建需要 Rust 1.82 以上。 英文可以使用 PDF 内置的 Helvetica；中文、日文、韩文等 Unicode 内容仍需要可用字体。可以让 CLI 查找系统 fallback fonts，也可以用 --fonts 指定自己的字体目录。 例如在生产环境中，可以只携带项目需要使用的字体： minipdf report.docx --fonts .\u002Ffonts -o report.pdf 4. 轻量化：Rust CLI 只有 3.35 MiB 先比较目前 repository 内已经构建完成的 Windows x64 release binary： 实现 可执行文件大小 Rust minipdf.exe 3,511,808 bytes（3.35 MiB） .NET Native AOT MiniPdf.Cli.exe 10,674,688 bytes（10.18 MiB） Rust CLI 大约是 .NET Native AOT CLI 的三分之一。 5. 实际环境测试 本次测试环境如下： 项目 环境 OS Windows 10 Pro 10.0.19045 CPU AMD Ryzen 5 5600X Rust toolchain cargo 1.96.0、rustc 1.96.0 .NET SDK 10.0.103 测试文件 Business expenses budget2.xlsx 输入大小 125,082 bytes 测试方式是让 Rust release CLI 与 .NET Native AOT CLI 转换同一份 XLSX，先预热一次，再分别启动五个独立 Process。每次验证 exit code、输出文件存在，而且 PDF header 是 %PDF-1.4；时间取五次中位数，Peak Working Set 则在 Process 存活期间采样。 第一组测试让两边都传入空的 --fonts 目录，避免系统字体扫描影响结果： 实现 时间中位数 Peak Working Set 中位数 PDF 大小 Rust 105.66 ms 15.72 MiB 464,432 bytes .NET Native AOT 632.99 ms 972.99 MiB 641,314 bytes 在这个案例中，Rust 约为 6 倍快，峰值 Working Set 也低很多。可以发现，Rust 原生引擎在不处理额外字体加载时，进程启动与转换路径相当精简。 但空字体目录不适合直接作为生产环境建议，因为缺少字体时，Unicode 文字的显示结果可能不同。这组数据主要用于隔离字体扫描成本。",3594,{"id":6,"kind":7,"title":11,"summary":13,"image":14,"href":15,"meta":17,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":37},"#2563eb","16 \u002F 10",[7,8],{"targetType":8,"targetId":9,"likedByMe":39,"likeCount":40,"commentCount":40,"contentLikeCount":40,"contentCommentCount":40,"sourceLikeCount":40,"sourceCommentCount":40},false,0,[42,51,57,64,72,79,85,92],{"id":43,"kind":7,"title":44,"summary":45,"image":46,"href":47,"meta":48,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":49},"NEWS_ARTICLE:827","MHS 三部曲（下）：谁允许 AI 行动？——权力、合规与中国厂商的答卷","我们总在等待一个像 ChatGPT 那样的机器人时刻。但具身智能真正的拐点，也许先发生在更不起眼的地方：一台陌生设备，第一次能把自己的能力、状态和边界完整告诉 AI；一个 Agent，第一次能把试出来的经验固化成可验证、可复用的机器技能。","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F510\u002F202608\u002F510-20260830153745229-1536981088.jpg","\u002Fnews\u002F827","2026 · 人工智能",[50],"人工智能",{"id":52,"kind":7,"title":53,"summary":54,"image":14,"href":55,"meta":17,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":56},"NEWS_ARTICLE:829","我不会美工，用 WorkBuddy 1 分钟做出 4 张海报","先说结果：下面这 4 张海报，从我发出指令到拿到图片，大约 1 分钟。 我不会美工，也没有打开 Photoshop。用的工具，是我之前用 WorkBuddy 做的一个海报生成器。这个生成器本身也没花几分钟，具体开发过程我在上一篇文章里写过。 这次我把海报生成器的网址、产品截图和要求一起发给 Work","\u002Fnews\u002F829",[7,8],{"id":58,"kind":7,"title":59,"summary":60,"image":61,"href":62,"meta":17,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":63},"NEWS_ARTICLE:828","一个人抵一个团队的时代，企业级 AI Agent 还需要做什么？","对于企业而言，真正需要的，不是一个“会聊天”的 Agent，而是一套能被多用户、多场景复用，且权限清晰、过程可审计、成本可控制的 Agent 能力体系。","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F2232255\u002F202609\u002F2232255-20260902173524728-659996478.png","\u002Fnews\u002F828",[7,8],{"id":65,"kind":7,"title":66,"summary":67,"image":14,"href":68,"meta":69,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":70},"NEWS_ARTICLE:832","用 runtime-async 写一个支持 async\u002Fawait 的轻量脚本引擎","起因：一个好奇 事情的开头很简单。 给 .NET 做过动态脚本的人大概都碰到过同一堵墙：表达式树也好、Reflection.Emit 也好，都很难支持 async\u002Fawait。原因不在语法，而在 await 的实现方式——C# 编译器要为每个 async 方法生成一个状态机结构体，把方法体切成若干片","\u002Fnews\u002F832","2026 · 软件开发",[71],"软件开发",{"id":73,"kind":7,"title":74,"summary":75,"image":76,"href":77,"meta":17,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":78},"NEWS_ARTICLE:831","Agent Sandbox 规模化：JuiceFS 探索与实践","过去一段时间，我们在和云厂商以及 Agent 团队推进 Sandbox 落地时，除了要解决数据如何进入 Sandbox，还需要考虑任务所需的数据和执行过程中产生的数据，如何跨任务、跨阶段持续使用。Sandbox 可以随任务快速创建和销毁，但数据往往需要继续保留、共享和流转。 当 Sandbox 并发","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F2544292\u002F202609\u002F2544292-20260902171045357-1907499098.png","\u002Fnews\u002F831",[7,8],{"id":80,"kind":7,"title":81,"summary":82,"image":14,"href":83,"meta":17,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":84},"NEWS_ARTICLE:830","百智云长期记忆服务：长期记忆与上下文窗口的区别","很多人在接触 AI 长期记忆时，第一反应是：「这不就是把聊天记录存起来吗？」其实这是一个很常见的误解。今天我们把「长期记忆」和「上下文窗口」这两个概念彻底讲清楚。 一、什么是上下文窗口 上下文窗口（Context Window）是模型在单次推理时能「看到」的文本上限。它像一个临时的工作台：模型只能处","\u002Fnews\u002F830",[7,8],{"id":86,"kind":7,"title":87,"summary":88,"image":89,"href":90,"meta":48,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":91},"NEWS_ARTICLE:835","体验向量数据库 qdrant","作者:张富春(ahfuzhang)，转载时请注明作者和引用链接，谢谢！ cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 背景 为了早点搞懂公司的百万行 C# 的祖传代码，我想在缺乏文档、缺乏帮手的情况下，先建立一个 企业知识库 来快速帮我理清头绪。 一开始，我是打算以 weav","https:\u002F\u002Fimg2022.cnblogs.com\u002Fblog\u002F1457949\u002F202202\u002F1457949-20220216153819145-1193738712.png","\u002Fnews\u002F835",[50],{"id":93,"kind":7,"title":94,"summary":95,"image":14,"href":96,"meta":17,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":97},"NEWS_ARTICLE:833","如何利用AI技术实现漫画翻译","漫画作为图文结合的特色文化载体，承载着各国潮流文化与人文故事，但跨语言的文字壁垒，长期制约着漫画的传播与交流。传统漫画翻译高度依赖人工操作，需要人工框选文字、擦除原图文字、翻译文案、排版适配画风，流程繁琐、耗时费力，且极易出现排版错乱、画风违和、语义偏差等问题。 随着深度学习、计算机视觉与大模型技术","\u002Fnews\u002F833",[7,8]]