115 lines
3.7 KiB
C#
115 lines
3.7 KiB
C#
|
|
using MiniExcelLibs;
|
|||
|
|
|
|||
|
|
using System.IO;
|
|||
|
|
|
|||
|
|
|
|||
|
|
namespace ShrlAlgoToolkit.RevitAddins.Common.Extensions
|
|||
|
|
{
|
|||
|
|
public static class MiniExcelExtensions
|
|||
|
|
{
|
|||
|
|
// --- 写入部分 (Write) ---
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 开始流式配置 Excel 写入
|
|||
|
|
/// </summary>
|
|||
|
|
public static Extensions.ExcelWriter<T> AsExcel<T>(this IEnumerable<T> data)
|
|||
|
|
{
|
|||
|
|
return new Extensions.ExcelWriter<T>(data);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 快速保存多 Sheet 字典到文件
|
|||
|
|
/// </summary>
|
|||
|
|
public static void SaveAsExcel(this Dictionary<string, object> sheetsData, string filePath, bool overwrite = true)
|
|||
|
|
{
|
|||
|
|
// 自动清理 Sheet 名称中的非法字符
|
|||
|
|
var sanitizedData = new Dictionary<string, object>();
|
|||
|
|
foreach (var kvp in sheetsData)
|
|||
|
|
{
|
|||
|
|
sanitizedData.Add(SanitizeSheetName(kvp.Key), kvp.Value);
|
|||
|
|
}
|
|||
|
|
MiniExcel.SaveAs(filePath, sanitizedData, overwriteFile: overwrite);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// --- 读取部分 (Read) ---
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从文件路径直接读取数据为强类型列表
|
|||
|
|
/// </summary>
|
|||
|
|
public static IEnumerable<T> ReadExcel<T>(this string filePath, string sheetName = null) where T : class, new()
|
|||
|
|
{
|
|||
|
|
if (!File.Exists(filePath)) throw new FileNotFoundException("Excel文件不存在", filePath);
|
|||
|
|
return MiniExcel.Query<T>(filePath, sheetName: sheetName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从文件路径读取为动态类型 (Dictionary/dynamic)
|
|||
|
|
/// </summary>
|
|||
|
|
public static IEnumerable<dynamic> ReadExcelDynamic(this string filePath, string sheetName = null)
|
|||
|
|
{
|
|||
|
|
if (!File.Exists(filePath)) throw new FileNotFoundException("Excel文件不存在", filePath);
|
|||
|
|
return MiniExcel.Query(filePath, sheetName: sheetName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// --- 工具方法 ---
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 清理 Excel Sheet 名称中的非法字符
|
|||
|
|
/// </summary>
|
|||
|
|
public static string SanitizeSheetName(string name)
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrEmpty(name)) return "Sheet1";
|
|||
|
|
char[] invalidChars = { '\\', '/', '?', '*', '[', ']', ':' };
|
|||
|
|
foreach (var c in invalidChars) name = name.Replace(c, '_');
|
|||
|
|
return name.Length > 31 ? name.Substring(0, 31) : name;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class ExcelWriter<T>
|
|||
|
|
{
|
|||
|
|
private readonly IEnumerable<T> data;
|
|||
|
|
private string sheetName = "Sheet1";
|
|||
|
|
private bool overwrite = true;
|
|||
|
|
|
|||
|
|
public ExcelWriter(IEnumerable<T> data) => this.data = data;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 设置 Sheet 名称
|
|||
|
|
/// </summary>
|
|||
|
|
public Extensions.ExcelWriter<T> WithSheetName(string name)
|
|||
|
|
{
|
|||
|
|
sheetName = Extensions.MiniExcelExtensions.SanitizeSheetName(name);
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 设置是否覆盖
|
|||
|
|
/// </summary>
|
|||
|
|
public Extensions.ExcelWriter<T> Overwrite(bool canOverwrite = true)
|
|||
|
|
{
|
|||
|
|
overwrite = canOverwrite;
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 执行保存到文件
|
|||
|
|
/// </summary>
|
|||
|
|
public void SaveTo(string filePath)
|
|||
|
|
{
|
|||
|
|
MiniExcel.SaveAs(filePath, data, sheetName: sheetName, overwriteFile: overwrite);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 转换为字节数组 (用于 Web 下载或内存操作)
|
|||
|
|
/// </summary>
|
|||
|
|
public byte[] ToBytes()
|
|||
|
|
{
|
|||
|
|
using (var ms = new MemoryStream())
|
|||
|
|
{
|
|||
|
|
ms.SaveAs(data, sheetName: sheetName);
|
|||
|
|
return ms.ToArray();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|