繼續在尋找比較快的xlsx寫入庫,從https://github.com/TinyXlsx/TinyXlsx/ 看到它的測試結果,比c++的openXLSX快幾倍,就想試用一下,仔細一看,它是個c#項目,需要.NET 8.0。
于是上微軟網站下載了.NET 8.0 SDK,解壓縮到c:\d\net8\目錄
又下載了TinyXlsx項目源代碼, 解壓縮到c:\d\TinyXlsx-main\目錄。
設置搜索路徑并編譯
set path=%path%;c:\d\net8
cd \d\tinyxlsx-maindotnet build TinyXlsx.sln --configuration Release
編譯成功,但不知怎么執行,進入編譯生成目標文件目錄找exe文件,只找到testhost.exe,但是執行報錯
cd C:\d\TinyXlsx-main\Tests\bin\Release\net8.0C:\d\TinyXlsx-main\Tests\bin\Release\net8.0>testhost
A fatal error occurred. The required library hostfxr.dll could not be found.
If this is a self-contained application, that library should exist in [C:\d\TinyXlsx-main\Tests\bin\Release\net8.0\].
If this is a framework-dependent application, install the runtime in the global location [C:\Program Files\dotnet] or use the DOTNET_ROOT environment variable to specify the runtime location or register the runtime location in [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x64\InstallLocation].The .NET Core runtime can be found at:- https://aka.ms/dotnet-core-applaunch?missing_runtime=true&arch=x64&rid=win10-x64
按照提示,又設置了環境變量DOTNET_ROOT,還是不對,只好請教DeepSeek
C:\d\TinyXlsx-main\Tests\bin\Release\net8.0>set DOTNET_ROOT=c:\d\net8C:\d\TinyXlsx-main\Tests\bin\Release\net8.0>testhost
A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'c:\d\net8'.
Failed to run as a self-contained app.- The application was run as a self-contained app because 'C:\d\TinyXlsx-main\Tests\bin\Release\net8.0\testhost.runtimeconfig.json' was not found.- If this should be a framework-dependent app, add the 'C:\d\TinyXlsx-main\Tests\bin\Release\net8.0\testhost.runtimeconfig.json' file and specify the appropriate framework.
他說:
這個錯誤是因為你的應用程序缺少運行時配置文件,并且沒有正確設置 .NET 運行時的路徑。以下是解決方案:
方法一:使用 dotnet 命令運行(推薦)
不要直接運行 testhost.exe
,而是使用 dotnet
命令:
cd C:\d\TinyXlsx-main\Tests\bin\Release\net8.0
dotnet testhost.dll
方法二:發布為自包含應用程序
重新構建項目,指定為自包含發布:
cd C:\d\TinyXlsx-main
dotnet publish Tests.csproj --configuration Release --runtime win-x64 --self-contained true
然后運行發布目錄中的可執行文件:
cd C:\d\TinyXlsx-main\Tests\bin\Release\net8.0\win-x64\publish
testhost.exe
方法三:修復環境變量設置
你設置的 DOTNET_ROOT
路徑不正確,應該指向包含 hostfxr.dll
的目錄:
set DOTNET_ROOT=C:\d\net8
set PATH=%DOTNET_ROOT%;%PATH%
然后重新運行。
方法四:檢查并修復運行時配置文件
確保 testhost.runtimeconfig.json
文件存在且內容正確。如果缺失,可以創建該文件:
{"runtimeOptions": {"tfm": "net8.0","framework": {"name": "Microsoft.NETCore.App","version": "8.0.0"}}
}
方法五:重新安裝或修復 .NET SDK
如果以上方法都不行,可能需要重新安裝 .NET SDK:
- 下載最新的 .NET 8 SDK
- 運行安裝程序
- 確保環境變量正確設置
最簡單的解決方案
直接使用這個命令:
cd C:\d\TinyXlsx-main
dotnet test
這會自動運行測試項目,無需手動處理運行時配置問題。
建議使用方法一或直接使用 dotnet test
命令,這是最標準的運行 .NET 測試方式。
我實驗了一下,dotnet test
命令可以執行成功,如下所示
cd C:\d\TinyXlsx-mainC:\d\TinyXlsx-main>dotnet test正在確定要還原的項目…所有項目均是最新的,無法還原。TinyXlsx -> C:\d\TinyXlsx-main\TinyXlsx\bin\Debug\net8.0\TinyXlsx.dllTests -> C:\d\TinyXlsx-main\Tests\bin\Debug\net8.0\Tests.dll
C:\d\TinyXlsx-main\Tests\bin\Debug\net8.0\Tests.dll (.NETCoreApp,Version=v8.0)的測試運行
VSTest 版本 17.11.1 (x64)正在啟動測試執行,請稍候...
總共 1 個測試文件與指定模式相匹配。已通過! - 失敗: 0,通過: 33,已跳過: 0,總計: 33,持續時間: 2 s - Tests.dll (net8.0)
其他命令仍然有錯,看生成的文件名后綴,都是dll,可能是動態鏈接庫,需要一個exe文件來調用,才能執行。
從TinyXlsx項目github主頁剪切了如下代碼,繼續問DeepSeek怎么才能執行。
using TinyXlsx;using var workbook = new Workbook("fileName.xlsx");
var worksheet = workbook.BeginSheet();for (var i = 1; i <= 100; i++)
{worksheet.BeginRow().WriteCellValue(true).WriteCellValue(123456).WriteCellValue(123.456m).WriteCellValue(123.456).WriteCellValue(DateTime.Now).WriteCellValue(DateTime.Now, "yyyy/MM/dd").WriteCellValue("Text")
}
workbook.Close();
他的回答
你可以創建一個簡單的控制臺應用程序來運行這個代碼生成 Excel 文件。以下是步驟:
方法一:創建控制臺應用程序
- 創建新的控制臺項目:
dotnet new console -n ExcelGenerator
cd ExcelGenerator
- 添加 TinyXlsx 包引用:
dotnet add package TinyXlsx
- 修改 Program.cs 文件:
using TinyXlsx;class Program
{static void Main(string[] args){using var workbook = new Workbook("fileName.xlsx");var worksheet = workbook.BeginSheet();for (var i = 1; i <= 100; i++){worksheet.BeginRow().WriteCellValue(true).WriteCellValue(123456).WriteCellValue(123.456m).WriteCellValue(123.456).WriteCellValue(DateTime.Now).WriteCellValue(DateTime.Now, "yyyy/MM/dd").WriteCellValue("Text");}workbook.Close();Console.WriteLine("Excel 文件生成完成!");}
}
- 編譯并運行:
dotnet run
方法二:直接在現有項目中運行
如果你已經有項目,可以:
- 在 Program.cs 中添加代碼:
using TinyXlsx;// 你的代碼
using var workbook = new Workbook("fileName.xlsx");
var worksheet = workbook.BeginSheet();for (var i = 1; i <= 100; i++)
{worksheet.BeginRow().WriteCellValue(true).WriteCellValue(123456).WriteCellValue(123.456m).WriteCellValue(123.456).WriteCellValue(DateTime.Now).WriteCellValue(DateTime.Now, "yyyy/MM/dd").WriteCellValue("Text");
}
workbook.Close();
- 運行項目:
dotnet run
方法三:使用單元測試(如果你有測試項目)
在測試項目中創建一個測試方法:
[Test]
public void GenerateExcelFile()
{using var workbook = new Workbook("testFile.xlsx");var worksheet = workbook.BeginSheet();for (var i = 1; i <= 100; i++){worksheet.BeginRow().WriteCellValue(true).WriteCellValue(123456).WriteCellValue(123.456m).WriteCellValue(123.456).WriteCellValue(DateTime.Now).WriteCellValue(DateTime.Now, "yyyy/MM/dd").WriteCellValue("Text");}workbook.Close();Assert.That(File.Exists("testFile.xlsx"), Is.True);
}
然后運行測試:
dotnet test
運行結果
成功運行后,你會在項目目錄下找到生成的 fileName.xlsx
文件。文件內容包含:
- 100 行數據
- 每行包含:布爾值、整數、小數、浮點數、日期時間、格式化日期、文本
注意: 確保你有寫入當前目錄的權限,或者指定完整的文件路徑,如:"C:\\temp\\fileName.xlsx"
我用方法一執行dotnet run成功,在當前目錄下生成了testFile.xlsx,內容也正確。從編譯生成的目標文件執行,也成功了。注意其實并不需要我提前下載tinyxlsx源代碼,dotnet add package TinyXlsx
命令會自動從存儲庫下載。
C:\d>dotnet new console -n wxlsx
已成功創建模板“控制臺應用”。正在處理創建后操作...
正在還原 C:\d\wxlsx\wxlsx.csproj:正在確定要還原的項目…已還原 C:\d\wxlsx\wxlsx.csproj (用時 51 毫秒)。
已成功還原。C:\d>cd wxlsxC:\d\wxlsx>dotnet add package TinyXlsx正在確定要還原的項目…Writing C:\Users\lt\AppData\Local\Temp\tmpnhly1b.tmp
info : X.509 證書鏈驗證將使用 .NET 選擇的默認信任存儲進行代碼簽名。
info : X.509 證書鏈驗證將使用 .NET 選擇的默認信任存儲進行時間戳。
info : 正在將包“TinyXlsx”的 PackageReference 添加到項目“C:\d\wxlsx\wxlsx.csproj”。
info : GET https://api.nuget.org/v3/registration5-gz-semver2/tinyxlsx/index.json
info : OK https://api.nuget.org/v3/registration5-gz-semver2/tinyxlsx/index.json 194 毫秒
info : 正在還原 C:\d\wxlsx\wxlsx.csproj 的包...
info : GET https://api.nuget.org/v3-flatcontainer/tinyxlsx/index.json
info : OK https://api.nuget.org/v3-flatcontainer/tinyxlsx/index.json 303 毫秒
info : GET https://api.nuget.org/v3-flatcontainer/tinyxlsx/0.2.0/tinyxlsx.0.2.0.nupkg
info : OK https://api.nuget.org/v3-flatcontainer/tinyxlsx/0.2.0/tinyxlsx.0.2.0.nupkg 316 毫秒
info : 已使用內容哈希 r8vOZYoY7y/pw5Jf6/4b2Lq1+b/STX0KdX6HKcnuSdv+cHmDFADsifgEV65QNiFhgvI6f4+iAGXfc/Y4NkHZQQ== 從 https://api.nuget.org/v3/index.json 到 C:\Users\lt\.nuget\packages\tinyxlsx\0.2.0 安裝 TinyXlsx 0.2.0。
info : GET https://api.nuget.org/v3/vulnerabilities/index.json
info : OK https://api.nuget.org/v3/vulnerabilities/index.json 185 毫秒
info : GET https://api.nuget.org/v3/vulnerabilities/vulnerability.base.json
info : GET https://api.nuget.org/v3/vulnerabilities/vulnerability.update.json
info : OK https://api.nuget.org/v3/vulnerabilities/vulnerability.base.json 278 毫秒
info : OK https://api.nuget.org/v3/vulnerabilities/vulnerability.update.json 515 毫秒
info : 包“TinyXlsx”與項目“C:\d\wxlsx\wxlsx.csproj”中指定的所有框架均兼容。
info : 包“TinyXlsx”(版本為 0.2.0)的 PackageReference 已添加到文件“C:\d\wxlsx\wxlsx.csproj”。
info : 將資產文件寫入磁盤。路徑: C:\d\wxlsx\obj\project.assets.json
log : 已還原 C:\d\wxlsx\wxlsx.csproj (用時 2.25 秒)。C:\d\wxlsx>dotnet run
Excel 文件生成完成!C:\d\wxlsx>cd C:\d\wxlsx\bin\Debug\net8.0C:\d\wxlsx\bin\Debug\net8.0>wxlsx
Excel 文件生成完成!
為了測試寫xlsx文件的效率,讓他每行隨機生成不同的數字、日期、字符串,結果如下
using TinyXlsx;
using System;class Program
{static void Main(string[] args){var random = new Random();using var workbook = new Workbook("fileName.xlsx");var worksheet = workbook.BeginSheet();for (var i = 1; i <= 100; i++){// 生成隨機數據var randomBool = random.Next(2) == 1;var randomInt = random.Next(1000000);var randomDecimal = (decimal)(random.NextDouble() * 1000);var randomDouble = random.NextDouble() * 1000;var randomDate = DateTime.Now.AddDays(random.Next(-365, 365));var randomText = $"Text_{random.Next(1000)}_{Guid.NewGuid().ToString().Substring(0, 8)}";worksheet.BeginRow().WriteCellValue(randomBool).WriteCellValue(randomInt).WriteCellValue(randomDecimal).WriteCellValue(randomDouble).WriteCellValue(randomDate).WriteCellValue(randomDate, "yyyy/MM/dd").WriteCellValue(randomText);}workbook.Close();Console.WriteLine("Excel 文件生成完成!");}
}
我把循環上限改為1000000,用前面的編譯本地文件命令生成的文件執行。
C:\d\wxlsx>dotnet publish wxlsx.csproj --configuration Release --runtime win-x64 --self-contained true正在確定要還原的項目…所有項目均是最新的,無法還原。wxlsx -> C:\d\wxlsx\bin\Release\net8.0\win-x64\wxlsx.dllwxlsx -> C:\d\wxlsx\bin\Release\net8.0\win-x64\publish\C:\d\wxlsx>..\timer64 C:\d\wxlsx\bin\Release\net8.0\win-x64\publish\wxlsx
Excel 文件生成完成!Kernel Time = 0.171 = 6%
User Time = 2.328 = 92%
Process Time = 2.500 = 99% Virtual Memory = 17 MB
Global Time = 2.506 = 100% Physical Memory = 37 MB
2秒鐘生成了100萬行7列的xlsx文件,大小是76MB,用壓縮工具檢查,它包含共享字符串sharedStrings.xml文件,但其中沒有條目,每個字符串都內聯保存在sheet1.xml中。
補記
繼續下載了.NET 8.0 SDK Linux版, 在WSL中體驗,結果操作與windows版幾乎完全一致,而且比Windows版更好的是,在下載成功頁面提供了詳細配置命令。以下是操作步驟
:/mnt/c/d# mkdir dotnet
:/mnt/c/d# cd dotnet
:/mnt/c/d/dotnet# tar xf ../dotnet-sdk-8.0.413-linux-x64.tar.gz
:/mnt/c/d/dotnet# export DOTNET_ROOT=/mnt/c/d/dotnet
:/mnt/c/d/dotnet# export PATH=$PATH:/mnt/c/d/dotnet:/mnt/c/d# dotnet new console -n lxlsx
:/mnt/c/d# cd lxlsx
:/mnt/c/d/lxlsx# dotnet add package TinyXlsx修改Program.cs并保存:/mnt/c/d/lxlsx# dotnet publish lxlsx.csproj --configuration Release --runtime linux-x64 --self-contained trueDetermining projects to restore...Restored /mnt/c/d/lxlsx/lxlsx.csproj (in 5.9 sec).lxlsx -> /mnt/c/d/lxlsx/bin/Release/net8.0/linux-x64/lxlsx.dlllxlsx -> /mnt/c/d/lxlsx/bin/Release/net8.0/linux-x64/publish/
:/mnt/c/d/lxlsx# time /mnt/c/d/lxlsx/bin/Release/net8.0/linux-x64/publish/lxlsx
Excel 文件生成完成!real 0m5.609s
user 0m3.271s
sys 0m0.458s
生成時間略長,生成的文件也略大,約83MB。