using System.Data; using Infrastructure; using Infrastructure.Utils; using Microsoft.Extensions.Options; using NetTopologySuite; using NetTopologySuite.Geometries; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using OpenAuth.App.BaseApp.Base; using OpenAuth.App.Interface; using OpenAuth.App.ServiceApp.LayerManagerApp.Request; using OpenAuth.Repository; using OpenAuth.Repository.Domain; using SqlSugar; namespace OpenAuth.App.ServiceApp.LayerManagerApp; public class LayerApp : SqlSugarBaseApp { private readonly string _filePath; private readonly ISqlSugarClient _client; public LayerApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth, IOptions setOptions, ISqlSugarClient client) : base(unitWork, repository, auth) { _client = client; _filePath = setOptions.Value.UploadPath; if (string.IsNullOrEmpty(_filePath)) { _filePath = AppContext.BaseDirectory; } } public async Task> UploadExcel(LayerReq req) { using var db = Repository.AsSugarClient(); var excelPath = Path.Combine(_filePath, req.FilePath); // excel名称 var excelFileName = Path.GetFileNameWithoutExtension(excelPath); // 使用NPOI读取Excel文件 using (var fileStream = new FileStream(excelPath, FileMode.Open, FileAccess.Read)) { IWorkbook workbook; if (Path.GetExtension(excelPath).Equals(".xls")) { workbook = new HSSFWorkbook(fileStream); } else { workbook = new XSSFWorkbook(fileStream); } // var sheet = workbook.GetSheetAt(0); // 获取总行数 var rowCount = sheet.LastRowNum; if (rowCount < 3) { throw new Exception("只有两行表头"); } // 获取总列数 var columnCount = sheet.GetRow(0).LastCellNum; var headers = new List(); // 遍历表头 var chineseRow = sheet.GetRow(0); var englishRow = sheet.GetRow(1); for (var j = 0; j < columnCount; j++) { var header = new DataTableAttr { InitName = chineseRow.GetCell(j).ToString(), // 中文表头 RefName = englishRow.GetCell(j).ToString()?.ToLower(), // 英文表头 // 字段类型 Type = "string", // 原始字段名称 Name = englishRow.GetCell(j).ToString(), // 字段长度 Length = 64 }; headers.Add(header); } var keys = headers.Select(a => a.RefName).ToList(); if (!keys.Contains("lng") || !keys.Contains("lat")) { throw new Exception("缺少经纬度字段"); } var typeBuilder = db.DynamicBuilder().CreateClass(req.DataTable, new SugarTable() { TableName = req.DataTable, TableDescription = req.ServerName + "图斑" }); //添加主键 typeBuilder.CreateProperty("id", typeof(string), new SugarColumn() { IsPrimaryKey = true, IsIdentity = false, ColumnDataType = "varchar", Length = 36, ColumnDescription = "主键", }); //添加主键 typeBuilder.CreateProperty("geometry", typeof(string), new SugarColumn() { IsPrimaryKey = false, IsIdentity = false, // ColumnDataType = "geometry(GEOMETRY)", ColumnDataType = string.Concat("geometry(GEOMETRY,", req.SpatialRef.AsSpan(req.SpatialRef.LastIndexOf(":", StringComparison.Ordinal) + 1), ")"), ColumnDescription = "图斑", }); headers.ForEach(u => { if (!u.RefName.Equals("lng") && !u.RefName.Equals("lat")) { typeBuilder.CreateProperty(u.RefName, typeof(string), new SugarColumn() { IsPrimaryKey = false, IsIdentity = false, IsNullable = true, Length = u.Length, ColumnDescription = u.InitName, }); } }); // 开启事务 await db.Ado.BeginTranAsync(IsolationLevel.ReadCommitted); // 创建表 //db.CodeFirst.InitTables(typeBuilder.BuilderType()); var cols = new string[headers.Count]; for (var i = 0; i < headers.Count; i++) { if (headers[i].RefName.Equals("lng")) { cols[i] = "geometry"; } else if (headers[i].RefName.Equals("lat")) { cols[i] = "id"; } else { cols[i] = headers[i].RefName; } } var objs = new List>(1001); var num = 0; // 遍历数据行 for (var i = 2; i < rowCount; i++) { var row = sheet.GetRow(i); if (row == null) { continue; } var data = new Dictionary(); // 遍历列 string lat = null, lng = null; for (var j = 0; j < columnCount; j++) { var cell = row.GetCell(j); if (cell == null) { continue; } var cellValue = cell.ToString(); switch (headers[j].RefName) { case "lat": lat = cellValue; continue; case "lng": lng = cellValue; continue; default: data[headers[j].RefName] = cellValue; break; } } if (lat != null && lng != null) { var geography = NtsGeometryServices.Instance.CreateGeometryFactory( int.Parse(req.SpatialRef.Substring( req.SpatialRef.IndexOf(":", StringComparison.Ordinal) + 1))); var point = geography.CreatePoint(new Coordinate(double.Parse(lng), double.Parse(lat))); data["geometry"] = point.AsText(); } data["id"] = Guid.NewGuid().ToString(); objs.Add(data); if (num++ == 999) { await db.Insertable(objs) .AS(req.DataTable) // 指定目标表名 .InsertColumns(cols) // 指定要插入的列 .ExecuteCommandAsync(); num = 0; objs.Clear(); } } await db.Insertable(objs) .AS(req.DataTable) // 指定目标表名 .InsertColumns(cols) // 指定要插入的列 .ExecuteCommandAsync(); await db.Ado.CommitTranAsync(); workbook.Close(); // 关于图层发布失败后,如何处理? // excel 矢量点发布图层 var response = await GeoUtil.CreateStoreAndLayer("", req.SpatialRef, req.DataTable, ""); // todo 保存图层信息 var dmLayer = new DmLayer() { Id = Guid.NewGuid().ToString(), SeverName = req.ServerName, SpatialRef = req.SpatialRef, SeverType = req.SeverType, // 服务类型 StoreType = "", //存储类型 DataSourceType = req.DataSourceType, TableRef = req.DataTable, ShapeType = req.ShapeType, StyleName = req.StyleName, // 样式名称 Description = req.Description, // 描述 Screenshot = req.Screenshot // 截图 }; await Repository.AsSugarClient().Insertable(dmLayer).ExecuteCommandAsync(); } return new Response { Result = true }; } public async Task> UploadShape(LayerReq req) { try { } catch (Exception ex) { throw new CommonException(ex.Message, 500); } return new Response { Result = true }; } }