发个自制的假表格导出到Excel的插件
本帖最后由 ThinkerHua 于 2025-2-20 13:22 编辑2025-02-19 19:29 更新
重构代码,由原来的“通过微软公开的 API 与 Excel 进行交互”,改为使用NPOI库直接读写文件,极大地提升了速度,瞬间即可完成。
并且现在支持.NET Framework 4.8(AutoCAD 2024 及以下) 和 .NET 8.0(AutoCAD 2025)。
压缩包内文件较多,"Common.dll" 和 "ExportTableToExcel.dll" 这两个文件是本人编写,其他 *.dll 文件是引用库,加载的时候仅需加载 "ExportTableToTable.dll"即可。
2024-12-26 18:45 更新
有网友提出合并单元格、斜线表头还有富文本的问题。
对于合并单元格,先给个解决方案,增加一个是否合并单元格的选项(本身就处理地不是很好,不合并还能稍微提升一下执行速度),附件已更新了。
对于斜线表头这个我想了下,应该是实现不了的,有些斜线表头横向或竖向跨了多个表格,用Excel的单元格框线是画不出来的,除非用插入形状里面的直线。
对于富文本问题,我已搜索到相关的文档,看了一下,挺复杂的,就先不去实现了吧。如果有谁有兴趣的话,可以拿我的代码去修改。
2024-12-26 09:51 更新
根据@longer1000 提供的报错样例,添加了容许误差功能,小于此数值的斜线将被视为水平或垂直。
原版内容
网上有同类插件,不过要么收费,要么存在一些问题。比如“CAD快速看图”,速度还是比较快的,但如果是很大的表格,会弹窗提示内容太多不工作,于是开发此插件。
本插件虽效率不及“CAD快速看图”,但无论表格内容多少均可使用。“CAD快速看图”估计是直接对 *.xls 文件进行读写的,所以比较快;本插件通过微软公开的 API 与 Excel 进行交互,效率较慢。
这里只放出编译好的文件,要源码的话可以去我的Github仓库去下载,现有三个项目,都是些小工具,如果对你有用话请帮我点个星:
Muggle AutoCAD-Plugins -- 用于AutoCAD的工具和插件。基于AutoCAD 2021版本开发,其他版本未经测试。
Muggle Tekla-Plugins -- 用于Tekla Structures的工具和插件。基于Tekla Structures 2021版本开发,其他版本未经测试。
Section Steel Calculation Tool -- 用于辅助 Excel 计算钢结构工程量的工具,根据已填写的型钢规格,自动生成单位面积或单位重量或加劲肋规格;还可以定位到指定类型型钢的单元格区域。
下载内容
下载解压后,AutoCAD中用netload命令加载“ExportTableToExcel.dll”即可,启动命令为“ETTE”或“ExprotTableToExcel”
借花献佛,分享在楼主源码基础上修改的导出csv的源码,感谢楼主的思路分享
public static class CsvExporter
{
public static void ExportToCsv(string excelFilePath)
{
try
{
// 检查文件是否存在
if (!File.Exists(excelFilePath))
{
MessageBox.Show("Excel文件不存在!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 确定CSV文件路径
string csvFilePath = Path.ChangeExtension(excelFilePath, ".csv");
// 读取Excel文件
using (FileStream fs = new FileStream(excelFilePath, FileMode.Open, FileAccess.Read))
{
HSSFWorkbook workbook = new HSSFWorkbook(fs);
ISheet sheet = workbook.GetSheetAt(0); // 获取第一个工作表
// 创建StringBuilder来构建CSV内容
StringBuilder csvContent = new StringBuilder();
// 遍历每一行
for (int rowIndex = 0; rowIndex <= sheet.LastRowNum; rowIndex++)
{
IRow row = sheet.GetRow(rowIndex);
if (row == null) continue;
List<string> rowData = new List<string>();
// 遍历每一列
for (int colIndex = 0; colIndex < row.LastCellNum; colIndex++)
{
ICell cell = row.GetCell(colIndex);
rowData.Add(GetCellValue(cell));
}
// 将行数据转换为CSV格式
csvContent.AppendLine(string.Join(",", rowData.ToArray()));
}
// 写入CSV文件
string csvContentStr = csvContent.ToString();
byte[] bytes = Encoding.Default.GetBytes(csvContentStr);
csvContentStr = Encoding.Default.GetString(bytes);
File.WriteAllText(csvFilePath, csvContentStr, Encoding.Default);
MessageBox.Show($"CSV文件已成功导出到:\n{csvFilePath}", "成功",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
MessageBox.Show($"导出CSV文件时出错:\n{ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private static string GetCellValue(ICell cell)
{
if (cell == null) return "";
switch (cell.CellType)
{
case CellType.String:
return EscapeCsvValue(cell.StringCellValue);
case CellType.Numeric:
return cell.NumericCellValue.ToString();
case CellType.Boolean:
return cell.BooleanCellValue.ToString();
case CellType.Formula:
return GetCellValue(cell);
default:
return "";
}
}
private static string EscapeCsvValue(string value)
{
if (value.Contains(",") || value.Contains("\"") || value.Contains("\n"))
{
return $"\"{value.Replace("\"", "\"\"")}\"";
}
return value;
}
} longer1000 发表于 2024-12-29 09:06
感谢,现在测试没问题,发现2个小问题,1导出的数据都是以文本格式,2、列宽不匹配
特地设置成文本格式的,因为有些数据会被Excel自动改为日期格式,设置成文本格式是为了避免此问题。如果确定不存在此类数据的话,可以手动全选表格设置成常规格式。
更新说明里已提到,富文本格式太复杂,我不想费脑筋去整这个。列宽问题,自己手动全选表格,双击自动设置列宽吧。 好烦的网站 发表于 2024-12-26 16:58
win1164位 24H2
没辙了,.net framework 是确定有Marshal.GetActiveObject 方法的,网上搜索到的信息是.net 5.0发布后就没这个方法了。但是Win11是自带.net framework 4.8的。这个情况我也不知道怎么解决。 弹出这个错误对话框,能不能提供一个测试文件 试了下,对带上下标的文字和斜线表头,处理得不够理想。 大佬真是多产,连发了两个。 本帖最后由 ThinkerHua 于 2024-12-25 23:01 编辑
longer1000 发表于 2024-12-25 19:29
弹出这个错误对话框,能不能提供一个测试文件
更新了测试用例,我有空看看为什么报错,你的报错文件能发出来看看吗? lzspain 发表于 2024-12-25 19:30
试了下,对带上下标的文字和斜线表头,处理得不够理想。
好的,有空研究一下吧。因为我自己用来导出数据的,所以对格式这块没有处理。 测试ok,可以满足绝大部分的表格,收藏! ThinkerHua 发表于 2024-12-25 22:57
好的,有空研究一下吧。因为我自己用来导出数据的,所以对格式这块没有处理。
麻烦您看看呢
CAD导出表格,先留名看看! 如果直线不封闭的表格可能输出会合并成一个单元格里面