NET 5 Execl导入数据处理(EppLus、NPOI)
先来简单介绍下市面上最广泛常见的三种操作excel库的优缺点
1.NPOI
优点:免费开源,无需装Office即可操作excel, 支持处理的文件格式包括xls, xlsx, docx.格式
缺点:不支持大数据量以及多sheet的导出
2.Aspose.Cells
优点:支持大数据量以及多sheet的导出,提供了应有尽有的文件格式支持,速度快性能佳
缺点:除了收费几乎没有缺点,试用版 限制打开文件数量100个,限制使用Aspose.Cells.GridWeb功能,生成的Excel会有水印
3.EPPlus
优点:开源免费,不需要安装office,支持图表的列印,导入导出速度快,支持高版本Excel格式,可以实现Excel上的各种基本功能
唯一缺点:仅支持xlsx格式,不支持古老的xlsx
基于业务需求和各大库优缺点对比,尽量选择合适业务需求的库,个人比较推荐的是EPPlus
本文使用的是EPPlus包来实现数据的导出,因为5.0以上的版本需要商业授权码,所以使用的是4.5.3.3的的版本
项目也是基于最新版本的.net core 3.1 web api
右键管理NuGet包添加EPPlus 选择版本添加项目引用
然后代码附上
创建excel导入帮助类Export2Excel.cs,为了使所有的地方通用,通过list泛型参数 传入数据源以及需要导出的字段标题,返回byte[],
以便直接写入文件流,也提供了基于DataTable 的操作
1、Excel .xls 和 .xlsx 有什么区别?#
区别如下:
1、文件格式不同。.xls 是一个特有的二进制格式,其核心结构是复合文档类型的结构,而.xlsx 的核心结构是 XML 类型的结构,
采用的是基于 XML 的压缩方式,使其占用的空间更小。.xlsx 中最后一个 x 的意义就在于此。
2、版本不同。.xls是excel2003及以前版本生成的文件格式,而.xlsx是excel2007及以后版本生成的文件格式。
3、兼容性不同。.xlsx格式是向下兼容的,可兼容.xls格式。
2、一号种子选手(EppLus)#
EPPlus是一个使用Open Office XML(xlsx)文件格式,能读写Excel 2007/2010 文件的开源组件,
在导出Excel的时候不需要电脑上安装office,官网为:http://epplus.codeplex.com/。
基本上Excel上的各种功能(例如图表、VBA、数据透视表、加密、数据验证等)Epplus都能实现,
它的一个缺点就是不支持导出2003版的Excel,也就是.XLS文件。
2.1 EppLus实现#
(1)添加包 EPPlus (注意:EPPlus.Core已弃用)
(2)Execl导入数据使用EPPlus处理实例:
/// <summary>
/// 获取Exel批量用户数据(EppLus)
/// </summary>
/// <param name="context"></param>
/// <param name="msg"></param>
/// <returns></returns>
public List<BatchUsersReq> GetBatchUsersData(HttpContext context,out string msg)
{
msg = "数据处理成功";
// 获取上传文件后缀
var extension = Path.GetExtension(context.Request.Form.Files[0].FileName).ToUpper();
if(!extension.Contains("XLSX"))
{
msg = "文件格式不正确,只支持XLSX文件";
return null;
}
// 限制单次只能上传5M
float fileSize = context.Request.Form.Files[0].Length / 1024 / 1024;
if(fileSize > 5)
{
msg = "文件大小超过限制";
return null;
}
try
{
Stream stream = context.Request.Form.Files[0].OpenReadStream();
using (var package = new ExcelPackage(stream))
{
// 获取Exel指定工作簿,"Sheet1"也可以用索引代替
ExcelWorksheet worksheet = package.Workbook.Worksheets["Sheet1"];
// 获取数据行数
int RowNum = worksheet.Dimension.Rows;
// 待处理数据存储列表
List<BatchUsersReq> usersData = new List<BatchUsersReq>();
// 获取每行数据
for (int row = 1; row <= RowNum; row++)
{
usersData.Add(new BatchUsersReq
{
// 获取每列数据
Account = worksheet.Cells[row, 1].Value.ToString(),
Password = worksheet.Cells[row, 2].Value.ToString(),
Name = worksheet.Cells[row, 3].Value.ToString(),
Sex = worksheet.Cells[row, 4].Value.ToString(),
UserRole = worksheet.Cells[row, 5].Value.ToString()
});
}
return usersData;
}
}
catch(Exception e)
{
msg = "数据异常";
}
return null;
}
3、二号种子选手(NPOI)
NPOI是一个开源项目,可以读/写xls,doc,ppt文件,有着广泛的应用。NPIO官网地址:http://npoi.codeplex.com/
使用NPOI能够帮助开发者在没有安装微软Office的情况下读写Office 97-2003的文件,支持的文件格式包括xls, doc, ppt等。
NPOI是构建在POI 3.x版本之上的,它可以在没有安装Office的情况 下对Word/Excel文档进行读写操作。
3.1 NPOI实现
(1)添加包 DotNetCore.NPOI
(2)Execl导入数据使用EPPlus处理实例:
/// <summary>
/// 获取Execl批量用户数据 NPOI
/// </summary>
/// <param name="file">execl</param>
/// <param name="msg"></param>
/// <returns></returns>
public List<BatchUsersReq> GetBatchUsersData(IFormFile file,out string msg)
{
msg = "数据处理成功";
// 获取上传文件后缀
string ext = Path.GetExtension(file.FileName).ToLower();
if(!ext.Contains("xls") && !ext.Contains("xlsx"))
{
msg = "文件有误,只支持上传XLS、XLSX文件";
return null;
}
// 限制单次只能上传5M
float fileSize = file.Length / 1024 / 1024;
if (fileSize > 5)
{
msg = "文件大小超过限制";
return null;
}
try
{
// 文件流处理
MemoryStream ms = new MemoryStream();
file.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
// 根据Excel版本进行处理
IWorkbook workbook = ext == ".xls" ? (IWorkbook)new HSSFWorkbook(ms) : new XSSFWorkbook(ms);
// 获取Excel第一张工作簿
ISheet sheet = workbook.GetSheetAt(0);
// 获取数据行数
int num = sheet.LastRowNum;
// 待处理用户数据
List<BatchUsersReq> users = new List<BatchUsersReq>();
for (int i = 1; i <= num; i++)
{
// 获取指定行数据
IRow row = sheet.GetRow(i);
BatchUsersReq user = new BatchUsersReq();
// 获取指定列数据
user.Account = row.GetCell(0).ToString();
user.Password = row.GetCell(1).ToString();
user.Name = row.GetCell(2).ToString();
user.Sex = row.GetCell(3).ToString();
user.UserRole = row.GetCell(4).ToString();
users.Add(user);
}
return users;
}
catch(Exception e)
{
msg = "数据处理出错";
}
return null;
}
4、踩坑心得
在使用一个库之前一定要多了解全面,多几个库对比然后选择符合自己需求的。
我刚开始参考的EppLus博文里面并没有说Epplus不支持.xls,IF判断逻辑也是两种都支持。
而我恰巧是上传的.xls格式,导致代码在读取工作簿的时候就报错,我以为是文件流的问题导致读取不到所以折腾了很久。
后来百度知道了Epplus不支持.xls,于是机智的我的直接手动把.xls改成了.xlsx。(哭唧唧)
结果当然还是不行,于是我又几番百度了解到了NPOI……
EppLus使用
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using OfficeOpenXml;
using OfficeOpenXml.Style; namespace Common.Utils
{
public class Export2Excel
{
/// <summary>
/// 生成excel
/// </summary>
/// <param name="dtSource">数据源</param>
/// <param name="title">标题(Sheet名)</param>
/// <param name="showTitle">是否显示</param>
/// <returns></returns>
public static MemoryStream Export(DataTable dtSource, string title, bool showTitle = true)
{
using (ExcelPackage package = new ExcelPackage())
{
ExcelWorksheet workSheet = package.Workbook.Worksheets.Add(title); int maxColumnCount = dtSource.Columns.Count;
int curRowIndex = 0; if (showTitle == true)
{
curRowIndex++;
//主题
workSheet.Cells[curRowIndex, 1, 1, maxColumnCount].Merge = true;
workSheet.Cells[curRowIndex, 1].Value = title;
var headerStyle = workSheet.Workbook.Styles.CreateNamedStyle("headerStyle");
headerStyle.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
headerStyle.Style.Font.Bold = true;
headerStyle.Style.Font.Size = 20;
workSheet.Cells[curRowIndex, 1].StyleName = "headerStyle"; curRowIndex++;
//导出时间栏
workSheet.Cells[curRowIndex, 1, 2, maxColumnCount].Merge = true;
workSheet.Cells[curRowIndex, 1].Value = "导出时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm");
workSheet.Cells[curRowIndex, 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;
} curRowIndex++;
var titleStyle = workSheet.Workbook.Styles.CreateNamedStyle("titleStyle");
titleStyle.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
titleStyle.Style.Font.Bold = true;
//标题
for (var i = 0; i < maxColumnCount; i++)
{
DataColumn column = dtSource.Columns[i];
workSheet.Cells[curRowIndex, i + 1].Value = column.ColumnName;
workSheet.Cells[curRowIndex, i + 1].StyleName = "titleStyle";
}
workSheet.View.FreezePanes(curRowIndex, 1);//冻结标题行 //内容
for (var i = 0; i < dtSource.Rows.Count; i++)
{
curRowIndex++;
for (var j = 0; j < maxColumnCount; j++)
{
DataColumn column = dtSource.Columns[j];
var row = dtSource.Rows[i];
object value = row[column];
var cell = workSheet.Cells[curRowIndex, j + 1];
var pType = column.DataType;
pType = pType.Name == "Nullable`1" ? Nullable.GetUnderlyingType(pType) : pType;
if (pType == typeof(DateTime))
{
cell.Style.Numberformat.Format = "yyyy-MM-dd hh:mm";
cell.Value = Convert.ToDateTime(value);
}
else if (pType == typeof(int))
{
cell.Value = Convert.ToInt32(value);
}
else if (pType == typeof(double) || pType == typeof(decimal))
{
cell.Value = Convert.ToDouble(value);
}
else
{
cell.Value = value == null ? "" : value.ToString();
}
workSheet.Cells[curRowIndex, j + 1].Value = row[column].ToString();
}
}
workSheet.Cells[workSheet.Dimension.Address].Style.Font.Name = "宋体";
workSheet.Cells[workSheet.Dimension.Address].AutoFitColumns();//自动填充
for (var i = 1; i <= workSheet.Dimension.End.Column; i++) { workSheet.Column(i).Width = workSheet.Column(i).Width + 2; }//在填充的基础上再加2
MemoryStream ms = new MemoryStream(package.GetAsByteArray());
return ms;
}
} /// <summary>
/// 生成excel
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dtSource">数据源</param>
/// <param name="columns">导出字段表头合集</param>
/// <param name="title">标题(Sheet名)</param>
/// <param name="showTitle">是否显示标题</param>
/// <returns></returns>
public static byte[] Export<T>(IList<T> dtSource, ExportColumnCollective columns, string title, bool showTitle = true)
{
using (ExcelPackage package = new ExcelPackage())
{
ExcelWorksheet workSheet = package.Workbook.Worksheets.Add(title); int maxColumnCount = columns.ExportColumnList.Count;
int curRowIndex = 0; //Excel标题
if (showTitle == true)
{
curRowIndex++;
workSheet.Cells[curRowIndex, 1, 1, maxColumnCount].Merge = true;
workSheet.Cells[curRowIndex, 1].Value = title;
var headerStyle = workSheet.Workbook.Styles.CreateNamedStyle("headerStyle");
headerStyle.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
headerStyle.Style.Font.Bold = true;
headerStyle.Style.Font.Size = 20;
workSheet.Cells[curRowIndex, 1].StyleName = "headerStyle"; curRowIndex++;
//导出时间
workSheet.Cells[curRowIndex, 1, 2, maxColumnCount].Merge = true;
workSheet.Cells[curRowIndex, 1].Value = "导出时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm");
workSheet.Cells[curRowIndex, 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;
} //数据表格标题(列名)
for (int i = 0, rowCount = columns.HeaderExportColumnList.Count; i < rowCount; i++)
{
curRowIndex++;
workSheet.Cells[curRowIndex, 1, curRowIndex, maxColumnCount].Style.Font.Bold = true;
var curColSpan = 1;
for (int j = 0, colCount = columns.HeaderExportColumnList[i].Count; j < colCount; j++)
{
var colColumn = columns.HeaderExportColumnList[i][j];
var colSpan = FindSpaceCol(workSheet, curRowIndex, curColSpan);
if (j == 0) curColSpan = colSpan;
var toColSpan = colSpan + colColumn.ColSpan;
var cell = workSheet.Cells[curRowIndex, colSpan, colColumn.RowSpan + curRowIndex, toColSpan];
cell.Merge = true;
cell.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
cell.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
workSheet.Cells[curRowIndex, colSpan].Value = colColumn.Title;
curColSpan += colColumn.ColSpan;
}
}
workSheet.View.FreezePanes(curRowIndex + 1, 1);//冻结标题行 Type type = typeof(T);
PropertyInfo[] propertyInfos = type.GetProperties();
if (propertyInfos.Count() == 0 && dtSource.Count > 0) propertyInfos = dtSource[0].GetType().GetProperties(); //数据行
for (int i = 0, sourceCount = dtSource.Count(); i < sourceCount; i++)
{
curRowIndex++;
for (var j = 0; j < maxColumnCount; j++)
{
var column = columns.ExportColumnList[j];
var cell = workSheet.Cells[curRowIndex, j + 1];
foreach (var propertyInfo in propertyInfos)
{
if (column.Field == propertyInfo.Name)
{
object value = propertyInfo.GetValue(dtSource[i]);
var pType = propertyInfo.PropertyType;
pType = pType.Name == "Nullable`1" ? Nullable.GetUnderlyingType(pType) : pType;
if (pType == typeof(DateTime))
{
cell.Style.Numberformat.Format = "yyyy-MM-dd hh:mm";
cell.Value = Convert.ToDateTime(value);
}
else if (pType == typeof(int))
{
cell.Style.Numberformat.Format = "#0";
cell.Value = Convert.ToInt32(value);
}
else if (pType == typeof(double) || pType == typeof(decimal))
{
if (column.Precision != null) cell.Style.Numberformat.Format = "#,##0.00";//保留两位小数 cell.Value = Convert.ToDouble(value);
}
else
{
cell.Value = value == null ? "" : value.ToString();
}
}
}
}
}
workSheet.Cells[workSheet.Dimension.Address].Style.Font.Name = "宋体";
workSheet.Cells[workSheet.Dimension.Address].AutoFitColumns();//自动填充
for (var i = 1; i <= workSheet.Dimension.End.Column; i++) { workSheet.Column(i).Width = workSheet.Column(i).Width + 2; }//在填充的基础上再加2 return package.GetAsByteArray();
}
} private static int FindSpaceCol(ExcelWorksheet workSheet, int row, int col)
{
if (workSheet.Cells[row, col].Merge)
{
return FindSpaceCol(workSheet, row, col + 1);
}
return col;
}
} //导出所需要映射的字段和表头集合
public class ExportColumnCollective
{
/// <summary>
/// 字段列集合
/// </summary>
public List<ExportColumn> ExportColumnList { get; set; }
/// <summary>
/// 表头或多表头集合
/// </summary>
public List<List<ExportColumn>> HeaderExportColumnList { get; set; }
}
//映射excel实体
public class ExportColumn
{ /// <summary>
/// 标题
/// </summary>
[JsonProperty("title")]
public string Title { get; set; }
/// <summary>
/// 字段
/// </summary>
[JsonProperty("field")]
public string Field { get; set; }
/// <summary>
/// 精度(只对double、decimal有效)
/// </summary>
[JsonProperty("precision")]
public int? Precision { get; set; }
/// <summary>
/// 跨列
/// </summary>
[JsonProperty("colSpan")]
public int ColSpan { get; set; }
/// <summary>
/// 跨行
/// </summary>
[JsonProperty("rowSpan")]
public int RowSpan { get; set; }
}
}
OK,有了通用帮助类库,剩下的就是针对具体业务所需而提供相应字段和表头的隐射,既可以实现文件的导出
别忘了添加引用命名空间using Common.Utils;
我们来看一下API
[HttpGet("ExportExcel")
public FileResult ExportExcel()
{
IList<Gogo> list = new List<Gogo>
{
new Gogo
{
Name = "张三",
Age = 18,
Card = "41234567890",
CreateTime = DateTime.Now,
},
new Gogo
{
Name = "李四",
Age = 20,
Card = "4254645461",
CreateTime = DateTime.Now,
},
};
//导出表头和字段集合
ExportColumnCollective ecc = new ExportColumnCollective();
//导出字段集合
ecc.ExportColumnList = new List<ExportColumn>
{
new ExportColumn{Field = "Name"},
new ExportColumn{Field = "Card"},
new ExportColumn{Field = "Age"},
new ExportColumn{Field = "CreateTime"},
};
//导出表头集合
ecc.HeaderExportColumnList = new List<List<ExportColumn>>
{
//使用list是为了后续可能有多表头合并列的需求,这里只需要单个表头所以一个list就ok了
new List<ExportColumn>
{
new ExportColumn{Title = "姓名"},
new ExportColumn{Title = "身份号"},
new ExportColumn{Title = "年龄"},
new ExportColumn{Title = "添加时间"}
},
//new List<ExportColumn>
//{
// new ExportColumn{Title = "子标题A",ColSpan = 1},
// new ExportColumn{Title = "子标题B",ColSpan = 1}
//},
};
byte[] result = Export2Excel.Export<Gogo>(list, ecc, "测试导出", false);
return File(result, "application/vnd.ms-excel", "导出报表.xlsx");
}
导入
[HttpPost]
public List<ExcelDemoDto> Import([FromForm] ImportExcelInput input)
{
var list = new List<ExcelDemoDto>(); using (var package = new ExcelPackage(input.ExcelFile.OpenReadStream()))
{
// 获取到第一个Sheet,也可以通过 Worksheets["name"] 获取指定的工作表
var sheet = package.Workbook.Worksheets.First(); #region 获取开始和结束行列的个数,根据个数可以做各种校验工作 // +1 是因为第一行往往我们获取到的都是Excel的标题
int startRowNumber = sheet.Dimension.Start.Row + 1;
int endRowNumber = sheet.Dimension.End.Row;
int startColumn = sheet.Dimension.Start.Column;
int endColumn = sheet.Dimension.End.Column; #endregion // 循环获取整个Excel数据表数据
for (int currentRow = startRowNumber; currentRow <= endRowNumber; currentRow++)
{
list.Add(new ExcelDemoDto
{
AAA = sheet.Cells[currentRow, 1].Text,
BBB = sheet.Cells[currentRow, 2].Text,
CCC = sheet.Cells[currentRow, 3].Text,
DDD = sheet.Cells[currentRow, 4].Text,
EEE = sheet.Cells[currentRow, 5].Text,
FFF = sheet.Cells[currentRow, 6].Text
});
}
} return list;
} public class ExcelDemoDto
{
public string AAA { get; set; }
public string BBB { get; set; }
public string CCC { get; set; }
public string DDD { get; set; }
public string EEE { get; set; }
public string FFF { get; set; }
} public class ImportExcelInput
{
public IFormFile ExcelFile { get; set; }
}
导出
[HttpGet]
public async Task<string> Export()
{
using var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("sheet1"); var headers = new string[] { "AAA", "BBB", "CCC", "DDD", "EEE", "FFF" };
for (int i = 0; i < headers.Length; i++)
{
worksheet.Cells[1, i + 1].Value = headers[i];
worksheet.Cells[1, i + 1].Style.Font.Bold = true;
} // 模拟数据
var list = new List<ExcelDemoDto>();
for (int i = 1; i <= 10; i++)
{
list.Add(new ExcelDemoDto
{
AAA = $"A{i}",
BBB = $"B{i}",
CCC = $"C{i}",
DDD = $"D{i}",
EEE = $"E{i}",
FFF = $"F{i}"
});
} // 支持各种直接获取数据的方法
// worksheet.Cells.Load*... int row = 2;
foreach (var item in list)
{
worksheet.Cells[row, 1].Value = item.AAA;
worksheet.Cells[row, 2].Value = item.BBB;
worksheet.Cells[row, 3].Value = item.CCC;
worksheet.Cells[row, 4].Value = item.DDD;
worksheet.Cells[row, 5].Value = item.EEE;
worksheet.Cells[row, 6].Value = item.FFF; row++;
} // 通常做法是,将excel上传至对象存储,获取到下载链接,这里将其输出到项目根目录。
var path = Path.Combine(Directory.GetCurrentDirectory(), $"excel.xlsx");
await package.GetAsByteArray().DownloadAsync(path);
return path;
}
NET 5 Execl导入数据处理(EppLus、NPOI)的更多相关文章
- MVC execl 导入导出
MVC execl 导入导出 <input id="xls" name="xls" type="file" style="w ...
- 基于NPOI的Execl导入导出例子
源地址:http://bbs.csdn.net/topics/390830774
- 【C#常用方法】2.DataTable(或DataSet)与Excel文件之间的导出与导入(使用NPOI)
DataTable与Excel之间的互导 1.项目添加NPOI的引用 NPOI项目简介: NPOI是一个开源的C#读写Excel.WORD等微软OLE2组件文档的项目,特点是可以在没有安装Office ...
- Execl导入问题之文本转换
前些天在基础数据的导入过程中,遇到了这样一个问题:数据明明存在,可是就是不识别!给出的错误提示是:该数据对应的外键不存在! 我找出其中的一条数据,在外键表中查询是存在的!问题出在哪里了呢? 从exec ...
- EXCEL数据导入数据库实例(NPOI)
Default.aspx 页面代码: 引用了: <script src="../../js/jquery.easyui.min.js" type="text/ ...
- execl 导入
/** * 导入Excel功能 是把execl表中的数据添加到数据表中 */ public function import(){ if (!empty($_FILES)) { $file = re ...
- .Net Core Excel导入导出神器Npoi.Mapper
前言 我们在日常开发中对Excel的操作可能会比较频繁,好多功能都会涉及到Excel的操作.在.Net Core中大家可能使用Npoi比较多,这款软件功能也十分强大,而且接近原始编程.但是直接使用Np ...
- c#.Net:Excel导入/导出之NPOI 2.0简介
NPOI 2.0+主要由SS, HPSF, DDF, HSSF, XWPF, XSSF, OpenXml4Net, OpenXmlFormats组成,具体列表如下: 资料来自:百度百科 Ass ...
- POI事件模型处理execl导入功能(只支持07版本的execl)
由于通过new XSSFWorkbook 这种方式导入导致生产环境端口宕机.通过dump文件和javacore文件分析是导入功能导致的.解决办法:自己通过网上写的工具类,不知道是否存在bug. pac ...
随机推荐
- Invalid operation updata 错误解决方法
错误: huny@DESKTOP-N1EBKQP:/mnt/c/Users/Administrator$ sudo apt-get updata E: Invalid operation updata ...
- Codeforces Round #674 (Div. 3)
A 除一下就完了. 时间复杂度 \(O\left(t\right)\). B 分在对称线上的矩阵和不在对称线上的矩阵讨论. 时间复杂度 \(O\left(tn^2\right)\). C 肯定是先增加 ...
- DevOps Workshop | 代码管理入门:基于代码扫描实现团队效率提升
CODING「DevOps Workshop 学习营地」持续火热进行中! 在这里,你可以轻松实践 DevOps 全流程.体验高效的云端开发.赢取精美礼品--第二期大奖「戴尔 U2718Q 显示器」将于 ...
- 【刷题笔记】DP优化-单调队列优化
单调队列优化 眼界极窄的ZZ之前甚至不会单调队列--(好丢人啊) 单调队列优化的常见情景: 转移可以转化成只需要确定一个维度,而且这个维度的取值范围在某个区间里 修剪草坪 这个题学长讲的好像是另外一个 ...
- Unity全局调用非静态函数
Unity全局调用非静态函数 情形 大概就是做游戏的时候想做一个给玩家展示信息的东西,比如玩家按了不该按的键提醒一下之类的.这个脚本倒是很简单,找个Text组件往上面加字就行了.问题在于这个脚本游戏中 ...
- moviepy AudioClip帧处理ValueError: The truth value of array with more than one element is ambiguous
☞ ░ 前往老猿Python博文目录 ░ 一.环境 操作系统:win7 64位 moviepy:1.0.3 numpy:1.19.0 Python:3.7.2 二.应用代码及报错信息 程序代码 if ...
- 老猿学5G:融合计费场景的Nchf_ConvergedCharging_Create、Update和Release融合计费消息交互过程
☞ ░ 前往老猿Python博文目录 ░ 一.Nchf_ConvergedCharging_Create交互过程 Nchf_ConvergedCharging_Create 服务为CTF向CHF请求提 ...
- 一个使用xlwings操作excel数据优化60倍处理效率的案例
☞ ░ 前往老猿Python博文目录 ░ 一.引言 老猿在将自己的博文数据(包括url地址.标题和阅读数量)从博客中获取后,使用xlwings保存到excel对象时发现,不同的处理方法性能相差非常大. ...
- 第13.1节 关于Python的异常处理
Python的异常网上有很多资料介绍,老猿就不再细说,在这里老猿只挑几件老猿认为重要的内容介绍一下. 一. 异常处理完整语法 异常处理的完整语法语法如下: try: - except (异常1,-,异 ...
- 记账本APP小升级
增加了显示当月总收入和总支出的功能,增加了选择收支类型的功能,删去了删除账目后恢复的功能. 1.数据库的升级 1.entity 添加了一个收支类型的字段: package com.example.ca ...