schangxiang@126.com
2025-05-21 496f78c085e7f8c5ba261835f9b8bda99c25b4cb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
using GenerateCode_GEBrilliantFactory;
using GenerateCode_WeiBen_WMS.Const;
using GenerateCode_WeiBen_WMS.Model;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace GenerateCode_WeiBen_WMS.Utility
{
 
    public class ImportTemplteHelper
    {
 
        /// <summary>
        /// 根据表名创建导入模版
        /// </summary>
        /// <param name="input"></param>
        public static void CreateImportTemplte(GenerateCodeParam input, List<ColumnModel> tableFieldList, string genCodeRootPath)
        {
            string errMsg = string.Empty;
            //业务名
            string _busName = input.EntityName;
            var copayPath = TemplateConst.EXCEL_TEMPLATEFILE_导入模版路径 + "\\CommonTemplate.xlsx";
 
            var fileFolderPath = genCodeRootPath + "\\server\\src\\CMS.Plugin." + input.NameSpacePath + "\\Resources\\Templates";
            if (!Directory.Exists(fileFolderPath))
            {
                Directory.CreateDirectory(fileFolderPath);
            }
            string newPath = fileFolderPath + $"\\{_busName}{TemplateConst.EXCEL_TEMPLATEFILE_导入模版名称后缀}.xlsx";
 
            CreatExcel(tableFieldList, copayPath, newPath);
        }
 
        /// <summary>
        /// 根据实体类名 生成导入excel模版
        /// </summary>
        /// <param name="tableFieldList">代码生成选择配置表的字段</param>
        /// <param name="copayPath"></param>
        /// <param name="newPath"></param>
        private static void CreatExcel(List<ColumnModel> tableFieldList, string copayPath, string newPath)
        {
            string errMsg = string.Empty;
            try
            {
                #region 验证原始导入模板文件是否存在
                if (!File.Exists(copayPath))
                {
                    errMsg = $"用来复制生成模版的EXCEL文件不存在";
                    throw new Exception($"生成导入模版文件异常:{errMsg}");
                }
                #endregion
 
                //获取模板文件
                FileInfo copyFile = new FileInfo(copayPath);
 
                // 检查新生成的导入模版文件是否存在,存在就删除,以避免可能的异常。
                if (File.Exists(newPath))
                {
                    File.Delete(newPath); // 删除文件
                }
                //复制原始导入模版,创建新的导入模版文件
                copyFile.CopyTo(newPath, true);
                FileInfo existingFile = new FileInfo(newPath);
                using (ExcelPackage package = new ExcelPackage(existingFile))
                {
                    //获取模板内容
                    ExcelWorksheet worksheet = package.Workbook.Worksheets[0];//获取第一个worksheet
                                                                              //行和列都是从1开始,而不是从0开始!!!
                    int _remarkRowIndex = 1;//worksheet 行索引(说明) 注意:默认是第一行是导入模版的说明
                    int _mergeRowCount = _remarkRowIndex;//合并行 (必填字段数量) 默认是第一行合并 
                    int _titleRowIndex = 1;//worksheet 行索引(标题)注意:默认是第一行是导入模版的标题
                    int _cellIndex = 1;//worksheet 列索引 注意:默认是第一列开始设置导入模版的标题
 
                    //模版第一列作为模版使用,所有新增的列样式报错一致
                    var templateCell = worksheet.Cells[_titleRowIndex, _cellIndex];
 
                    string _remark = string.Empty;  //第一行添加说明,注意换行。
 
                    //获取要处理的代码生成配置的是增改的模版字段
                    var showCodeGenConfigs = tableFieldList.Where(w => 1 == 1).ToList();
                    showCodeGenConfigs = showCodeGenConfigs.Where(x => 1 == 1).ToList();
 
                    /*
                   int _mergeCellsCount = showCodeGenConfigs.Count();//合并列(模版赋值的标题列数)
                                                                     //获取必填字段
 
                   //创建模版说明
                   StringBuilder _remarkContentBuilder = GetParseTemplateHint(showCodeGenConfigs);
                   string _remarkContent = _remarkContentBuilder.ToString();
 
                   #region 合并单元格
                   //合并单元格,合并行和列。默认是合并第一行的所有标题列
                   var cellRange = worksheet.Cells[1, 1, _mergeRowCount, _mergeCellsCount];
 
                   cellRange.Value = _remarkContent;//合并单元格后的内容赋值
                   var mergeCell = cellRange.Merge = true;//合并
                   int rowHeight = GetRowHeightBasedOnContent(showCodeGenConfigs.Count()); // 根据内容计算行高(这里需要你自己实现逻辑)
                   worksheet.Row(_remarkRowIndex).Height = rowHeight; // 设置行高,注意EPPlus的单位不同,需要转换
 
                   #endregion
                   //*/
 
                    //循环创建模版标题列
                    foreach (var item in showCodeGenConfigs)
                    {
                        var currentCell = worksheet.Cells[_titleRowIndex, _cellIndex];
                        //给新模版列标题赋值
                        currentCell.Value = item.Description;
                        //复制拷贝的excel模版列,给新模版列样式赋值
                        currentCell.StyleID = templateCell.StyleID;
                        // worksheet.Column(_cellIndex).AutoFit();//宽度自适应
 
                        //给第二行赋值
                        var currentCell2 = worksheet.Cells[2, _cellIndex];
                        //给新模版列标题赋值
                        currentCell2.Value = "{{配置." + item.ColumnName + "}}";
                        //复制拷贝的excel模版列,给新模版列样式赋值
                        //currentCell2.StyleID = templateCell.StyleID;
                        // worksheet.Column(_cellIndex).AutoFit();//宽度自适应
 
                        _cellIndex++;
                    }
 
 
                    package.Save();//保存
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"生成导入模版文件异常,请查看系统日志:" + ex.Message);
            }
            finally { }
        }
 
        // 这里是一个假设的方法,用于根据单元格内容计算行高。你需要根据实际情况来实现这个逻辑。
        private static int GetRowHeightBasedOnContent(int lineCount)
        {
            // 这里只是一个示例逻辑,你可能需要更复杂的算法来决定合适的行高。
 
            return (lineCount + 3) * 20; // 
        }
 
        private static StringBuilder GetParseTemplateHint(List<ColumnModel> requiredTableFieldList)
        {
            StringBuilder _remarkContentBuilder = new StringBuilder();
            _remarkContentBuilder.AppendLine("");
            _remarkContentBuilder.AppendLine("1.支持Excel2007及以上版本文件。");
            _remarkContentBuilder.AppendLine("2.导入数据时不能超过5000行。");
            _remarkContentBuilder.AppendLine("");
            _remarkContentBuilder.AppendLine("");
 
            Dictionary<string, string> typeNameDict = new Dictionary<string, string>()
            {
                { "string", "输入文本。"},
                { "int", "输入数字。"},
                { "long", "输入数字。"},
                { "decimal", "输入小数。"},
                { "bool", "是,否。"},
 
            };
            Dictionary<string, string> effectTypeDict = new Dictionary<string, string>()
            {
                { "datepicker", "日期。 示例: 2023/3/1。"},
                { "datetimepicker", "日期时间。示例: 2023/3/1 12:00:00。"},
 
            };
 
            requiredTableFieldList.ForEach(x =>
            {
                string text = "";
                text += x.Description + "(" + (x.IsNullable ? "必填" : "非必填") + "): ";
                var _dataType = x.DataType.Replace("?", "").ToLower();
                //if (effectTypeDict.ContainsKey(x.EffectType.ToLower()))
                //{
                //    text += effectTypeDict[x.EffectType.ToLower()];
                //}
                //else if (x.EffectType.ToLower() == "enumselector")
                //{//注意:这个判断要放在判断_dataType前面,主要是考虑枚举和int类型的混淆
                //    var queryValue = x.NetType.Split('.').Last();
                //    var enumStr = _sysEnumService.GetEnumDataListStr(new EnumDataInput() { EnumName = queryValue });
                //    text += enumStr + "。";
                //}
                if (typeNameDict.ContainsKey(_dataType))
                {
                    text += typeNameDict[_dataType];
                }
                else
                {
                    text += ("注意:类型未能识别出来,需要自己维护!!!。");
                }
                _remarkContentBuilder.AppendLine(text);
            });
 
            return _remarkContentBuilder;
 
        }
 
    }
}