ThinkerHua 发表于 2024-12-25 18:18:39

发个自制的假表格导出到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”





断崖 发表于 2025-3-30 18:25:57

借花献佛,分享在楼主源码基础上修改的导出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;
   }
}

ThinkerHua 发表于 2024-12-29 19:01:21

longer1000 发表于 2024-12-29 09:06
感谢,现在测试没问题,发现2个小问题,1导出的数据都是以文本格式,2、列宽不匹配

特地设置成文本格式的,因为有些数据会被Excel自动改为日期格式,设置成文本格式是为了避免此问题。如果确定不存在此类数据的话,可以手动全选表格设置成常规格式。

更新说明里已提到,富文本格式太复杂,我不想费脑筋去整这个。列宽问题,自己手动全选表格,双击自动设置列宽吧。

ThinkerHua 发表于 2024-12-26 17:19:44

好烦的网站 发表于 2024-12-26 16:58
win1164位   24H2

没辙了,.net framework 是确定有Marshal.GetActiveObject 方法的,网上搜索到的信息是.net 5.0发布后就没这个方法了。但是Win11是自带.net framework 4.8的。这个情况我也不知道怎么解决。

longer1000 发表于 2024-12-25 19:29:10

弹出这个错误对话框,能不能提供一个测试文件

lzspain 发表于 2024-12-25 19:30:12

试了下,对带上下标的文字和斜线表头,处理得不够理想。

煮茗 发表于 2024-12-25 20:27:28

大佬真是多产,连发了两个。

ThinkerHua 发表于 2024-12-25 22:56:01

本帖最后由 ThinkerHua 于 2024-12-25 23:01 编辑

longer1000 发表于 2024-12-25 19:29
弹出这个错误对话框,能不能提供一个测试文件
更新了测试用例,我有空看看为什么报错,你的报错文件能发出来看看吗?

ThinkerHua 发表于 2024-12-25 22:57:48

lzspain 发表于 2024-12-25 19:30
试了下,对带上下标的文字和斜线表头,处理得不够理想。

好的,有空研究一下吧。因为我自己用来导出数据的,所以对格式这块没有处理。

jkop 发表于 2024-12-25 23:06:12

测试ok,可以满足绝大部分的表格,收藏!

longer1000 发表于 2024-12-26 00:08:27

ThinkerHua 发表于 2024-12-25 22:57
好的,有空研究一下吧。因为我自己用来导出数据的,所以对格式这块没有处理。

麻烦您看看呢

weijiewen 发表于 2024-12-26 09:12:04

CAD导出表格,先留名看看!

sowin 发表于 2024-12-26 09:26:04

如果直线不封闭的表格可能输出会合并成一个单元格里面
页: [1] 2 3 4
查看完整版本: 发个自制的假表格导出到Excel的插件