在平时的业务系统开发中,少不了需要用到导出、导入excel功能,今天我们就一起来总结一下,如果你正为此需求感到困惑,那么阅读完本文,你一定会有所收获!
大概在很久很久以前,微软的电子表格软件 Excel 以操作简单、存储数据直观方便,还支持打印报表,在诞生之初,可谓深得办公室里的白领青睐,极大的提升了工作的效率,不久之后,便成了办公室里的必备工具。
随着更多的新语言的崛起,例如我们所熟悉的 java,后来便有一些团队开始开发一套能与 Excel 软件无缝切换的操作工具!
这其中就有我们所熟悉的 apache 的 poi,其前身是 Jakarta 的 POI Project项目,之后将其开源给 apache 基金会!
当然,在java生态体系里面,能与Excel无缝衔接的第三方工具还有很多,因为 apache poi 在业界使用的最广泛,因此其他的工具不做过多介绍!
话不多说,直接开撸!
<dependencies>
<!--xls(03)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<!--xlsx(07)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!--时间格式化工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.6</version>
</dependency>
</dependencies>
导出操作,即使用 Java 写出数据到 Excel 中,常见场景是将页面上的数据导出,这些数据可能是财务数据,也可能是商品数据,生成 Excel 后返回给用户下载文件。
在 poi 工具库中,导出 api 可以分三种方式
HSSF方式,最多只支持65536条数据导出,超过这个条数会报错!
public class ExcelWrite2003Test {
public static String PATH = "/Users/hello/Desktop/";
public static void main(String[] args) throws Exception {
//时间
long begin = System.currentTimeMillis();
//创建一个工作簿
Workbook workbook = new HSSFWorkbook();
//创建表
Sheet sheet = workbook.createSheet();
//写入数据
for (int rowNumber = 0; rowNumber < 65536; rowNumber++) {
//创建行
Row row = sheet.createRow(rowNumber);
for (int cellNumber = 0; cellNumber < 10; cellNumber++) {
//创建列
Cell cell = row.createCell(cellNumber);
cell.setCellValue(cellNumber);
}
}
System.out.println("over");
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "用户信息表2003BigData.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();
long end = System.currentTimeMillis();
System.out.println((double) (end - begin) / 1000);//4.29s
}
}
XSSF方式支持大批量数据导出,所有的数据先写入内存再导出,容易出现内存溢出!
public class ExcelWrite2007Test {
public static String PATH = "/Users/hello/Desktop/";
public static void main(String[] args) throws Exception {
//时间
long begin = System.currentTimeMillis();
//创建一个工作簿
Workbook workbook = new XSSFWorkbook();
//创建表
Sheet sheet = workbook.createSheet();
//写入数据
for (int rowNumber = 0; rowNumber < 65537; rowNumber++) {
Row row = sheet.createRow(rowNumber);
for (int cellNumber = 0; cellNumber < 10; cellNumber++) {
Cell cell = row.createCell(cellNumber);
cell.setCellValue(cellNumber);
}
}
System.out.println("over");
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "用户信息表2007BigData.xlsx");
workbook.write(fileOutputStream);
fileOutputStream.close();
long end = System.currentTimeMillis();
System.out.println((double) (end - begin) / 1000);//15.87s
}
}
SXSSF方式是XSSF方式的一种延伸,主要特性是低内存,导出的时候,先将数据写入磁盘再导出,避免报内存不足,导致程序运行异常,缺点是运行很慢!
public class ExcelWriteSXSSFTest {
public static String PATH = "/Users/hello/Desktop/";
public static void main(String[] args) throws Exception {
//时间
long begin = System.currentTimeMillis();
//创建一个工作簿
Workbook workbook = new SXSSFWorkbook();
//创建表
Sheet sheet = workbook.createSheet();
//写入数据
for (int rowNumber = 0; rowNumber < 100000; rowNumber++) {
Row row = sheet.createRow(rowNumber);
for (int cellNumber = 0; cellNumber < 10; cellNumber++) {
Cell cell = row.createCell(cellNumber);
cell.setCellValue(cellNumber);
}
}
System.out.println("over");
FileOutputStream fileOutputStream = new FileOutputStream(PATH + "用户信息表2007BigDataS.xlsx");
workbook.write(fileOutputStream);
fileOutputStream.close();
long end = System.currentTimeMillis();
System.out.println((double) (end - begin) / 1000);//6.39s
}
}
导入操作,即将 excel 中的数据采用java工具库将其解析出来,进而将 excel 数据写入数据库!
同样,在 poi 工具库中,导入 api 也分三种方式,与上面的导出一一对应!
public class ExcelRead2003Test {
public static String PATH = "/Users/hello/Desktop/";
public static void main(String[] args) throws Exception {
//获取文件流
FileInputStream inputStream = new FileInputStream(PATH + "用户信息表BigData.xls");
//1.创建工作簿,使用excel能操作的这边都看看操作
Workbook workbook = new HSSFWorkbook(inputStream);
//2.得到表
Sheet sheet = workbook.getSheetAt(0);
//3.得到行
Row row = sheet.getRow(0);
//4.得到列
Cell cell = row.getCell(0);
getValue(cell);
inputStream.close();
}
public static void getValue(Cell cell){
//匹配类型数据
if (cell != null) {
CellType cellType = cell.getCellType();
String cellValue = "";
switch (cellType) {
case STRING: //字符串
System.out.print("[String类型]");
cellValue = cell.getStringCellValue();
break;
case BOOLEAN: //布尔类型
System.out.print("[boolean类型]");
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case BLANK: //空
System.out.print("[BLANK类型]");
break;
case NUMERIC: //数字(日期、普通数字)
System.out.print("[NUMERIC类型]");
if (HSSFDateUtil.isCellDateFormatted(cell)) { //日期
System.out.print("[日期]");
Date date = cell.getDateCellValue();
cellValue = new DateTime(date).toString("yyyy-MM-dd");
} else {
//不是日期格式,防止数字过长
System.out.print("[转换为字符串输出]");
cell.setCellType(CellType.STRING);
cellValue = cell.toString();
}
break;
case ERROR:
System.out.print("[数据类型错误]");
break;
}
System.out.println(cellValue);
}
}
}
public class ExcelRead2007Test {
public static String PATH = "/Users/hello/Desktop/";
public static void main(String[] args) throws Exception {
//获取文件流
FileInputStream inputStream = new FileInputStream(PATH + "用户信息表2007BigData.xlsx");
//1.创建工作簿,使用excel能操作的这边都看看操作
Workbook workbook = new XSSFWorkbook(inputStream);
//2.得到表
Sheet sheet = workbook.getSheetAt(0);
//3.得到行
Row row = sheet.getRow(0);
//4.得到列
Cell cell = row.getCell(0);
getValue(cell);
inputStream.close();
}
public static void getValue(Cell cell){
//匹配类型数据
if (cell != null) {
CellType cellType = cell.getCellType();
String cellValue = "";
switch (cellType) {
case STRING: //字符串
System.out.print("[String类型]");
cellValue = cell.getStringCellValue();
break;
case BOOLEAN: //布尔类型
System.out.print("[boolean类型]");
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case BLANK: //空
System.out.print("[BLANK类型]");
break;
case NUMERIC: //数字(日期、普通数字)
System.out.print("[NUMERIC类型]");
if (HSSFDateUtil.isCellDateFormatted(cell)) { //日期
System.out.print("[日期]");
Date date = cell.getDateCellValue();
cellValue = new DateTime(date).toString("yyyy-MM-dd");
} else {
//不是日期格式,防止数字过长
System.out.print("[转换为字符串输出]");
cell.setCellType(CellType.STRING);
cellValue = cell.toString();
}
break;
case ERROR:
System.out.print("[数据类型错误]");
break;
}
System.out.println(cellValue);
}
}
}
public class ExcelReadSXSSFTest {
public static String PATH = "/Users/hello/Desktop/";
public static void main(String[] args) throws Exception {
//获取文件流
//1.创建工作簿,使用excel能操作的这边都看看操作
OPCPackage opcPackage = OPCPackage.open(PATH + "用户信息表2007BigData.xlsx");
XSSFReader xssfReader = new XSSFReader(opcPackage);
StylesTable stylesTable = xssfReader.getStylesTable();
ReadOnlySharedStringsTable sharedStringsTable = new ReadOnlySharedStringsTable(opcPackage);
// 创建XMLReader,设置ContentHandler
XMLReader xmlReader = SAXHelper.newXMLReader();
xmlReader.setContentHandler(new XSSFSheetXMLHandler(stylesTable, sharedStringsTable, new SimpleSheetContentsHandler(), false));
// 解析每个Sheet数据
Iterator<InputStream> sheetsData = xssfReader.getSheetsData();
while (sheetsData.hasNext()) {
try (InputStream inputStream = sheetsData.next();) {
xmlReader.parse(new InputSource(inputStream));
}
}
}
/**
* 内容处理器
*/
public static class SimpleSheetContentsHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
protected List<String> row;
/**
* A row with the (zero based) row number has started
*
* @param rowNum
*/
@Override
public void startRow(int rowNum) {
row = new ArrayList<>();
}
/**
* A row with the (zero based) row number has ended
*
* @param rowNum
*/
@Override
public void endRow(int rowNum) {
if (row.isEmpty()) {
return;
}
// 处理数据
System.out.println(row.stream().collect(Collectors.joining(" ")));
}
/**
* A cell, with the given formatted value (may be null),
* and possibly a comment (may be null), was encountered
*
* @param cellReference
* @param formattedValue
* @param comment
*/
@Override
public void cell(String cellReference, String formattedValue, XSSFComment comment) {
row.add(formattedValue);
}
/**
* A header or footer has been encountered
*
* @param text
* @param isHeader
* @param tagName
*/
@Override
public void headerFooter(String text, boolean isHeader, String tagName) {
}
}
}
easypoi 的底层也是基于 apache poi 进行深度开发的,它主要的特点就是将更多重复的工作,全部简单化,避免编写重复的代码!
<dependencies>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.1.0</version>
</dependency>
</dependencies>
easypoi 最大的亮点就是基于注解实体类来导出、导入excel,使用起来非常简单!
首先,我们创建一个实体类UserEntity,其中@Excel注解表示导出文件的头部信息。
public class UserEntity {
@Excel(name = "姓名")
private String name;
@Excel(name = "年龄")
private int age;
@Excel(name = "操作时间",format="yyyy-MM-dd HH:mm:ss", width = 20.0)
private Date time;
//set、get省略
}
接着,我们来编写导出服务!
public static void main(String[] args) throws Exception {
List<UserEntity> dataList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
UserEntity userEntity = new UserEntity();
userEntity.setName("张三" + i);
userEntity.setAge(20 + i);
userEntity.setTime(new Date(System.currentTimeMillis() + i));
dataList.add(userEntity);
}
//生成excel文档
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("用户","用户信息"),
UserEntity.class, dataList);
FileOutputStream fos = new FileOutputStream("/Users/hello/Documents/easypoi-user1.xls");
workbook.write(fos);
fos.close();
}
导出的文件预览如下:
对应的导入操作,也很简单,源码如下:
public static void main(String[] args) {
ImportParams params = new ImportParams();
params.setTitleRows(1);
params.setHeadRows(1);
long start = new Date().getTime();
List<StudentEntity> list = ExcelImportUtil.importExcel(new File("/Users/hello/Documents/easypoi-user1.xls"),
UserEntity.class, params);
System.out.println(new Date().getTime() - start);
System.out.println(JSONArray.toJSONString(list));
}
运行程序,输出结果如下:
[{"age":20,"name":"张三0","time":1616919493000},{"age":21,"name":"张三1","time":1616919493000},{"age":22,"name":"张三2","time":1616919493000},{"age":23,"name":"张三3","time":1616919493000},{"age":24,"name":"张三4","time":1616919493000},{"age":25,"name":"张三5","time":1616919493000},{"age":26,"name":"张三6","time":1616919493000},{"age":27,"name":"张三7","time":1616919493000},{"age":28,"name":"张三8","time":1616919493000},{"age":29,"name":"张三9","time":1616919493000}]
easypoi 同样也支持自定义数据结构导出导入excel。
public static void main(String[] args) throws Exception {
//封装表头
List<ExcelExportEntity> entityList = new ArrayList<ExcelExportEntity>();
entityList.add(new ExcelExportEntity("姓名", "name"));
entityList.add(new ExcelExportEntity("年龄", "age"));
ExcelExportEntity entityTime = new ExcelExportEntity("操作时间", "time");
entityTime.setFormat("yyyy-MM-dd HH:mm:ss");
entityTime.setWidth(20.0);
entityList.add(entityTime);
//封装数据体
List<Map<String, Object>> dataList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Map<String, Object> userEntityMap = new HashMap<>();
userEntityMap.put("name", "张三" + i);
userEntityMap.put("age", 20 + i);
userEntityMap.put("time", new Date(System.currentTimeMillis() + i));
dataList.add(userEntityMap);
}
//生成excel文档
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("学生","用户信息"), entityList, dataList);
FileOutputStream fos = new FileOutputStream("/Users/panzhi/Documents/easypoi-user2.xls");
workbook.write(fos);
fos.close();
}
public static void main(String[] args) {
ImportParams params = new ImportParams();
params.setTitleRows(1);
params.setHeadRows(1);
long start = new Date().getTime();
List<Map<String, Object>> list = ExcelImportUtil.importExcel(new File("/Users/panzhi/Documents/easypoi-user2.xls"),
Map.class, params);
System.out.println(new Date().getTime() - start);
System.out.println(JSONArray.toJSONString(list));
}
更多的 api 操作可以访问 Easypoi - 接口文档
easyexcel 是阿里巴巴开源的一款 excel 解析工具,底层逻辑也是基于 apache poi 进行二次开发的。不同的是,再读写数据的时候,采用 sax 模式一行一行解析,在并发量很大的情况下,依然能稳定运行!
下面,我们就一起来了解一下这款新起之秀!
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
<!--常用工具库-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
</dependencies>
easyexcel 同样也支持采用注解方式进行导出、导入!
首先,我们创建一个实体类UserEntity,其中@ExcelProperty注解表示导出文件的头部信息。
public class UserEntity {
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "年龄")
private int age;
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "操作时间")
private Date time;
//set、get省略
}
接着,我们来编写导出服务!
public static void main(String[] args) {
List<UserEntity> dataList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
UserEntity userEntity = new UserEntity();
userEntity.setName("张三" + i);
userEntity.setAge(20 + i);
userEntity.setTime(new Date(System.currentTimeMillis() + i));
dataList.add(userEntity);
}
EasyExcel.write("/Users/hello/Documents/easyexcel-user1.xls", UserEntity.class).sheet("用户信息").doWrite(dataList);
}
导出的文件预览如下:
对应的导入操作,也很简单,源码如下:
public static void main(String[] args) {
String filePath = "/Users/hello/Documents/easyexcel-user1.xls";
List<DemoData> list = EasyExcel.read(filePath).head(UserEntity.class).sheet().doReadSync();
System.out.println(JSONArray.toJSONString(list));
}
运行程序,输出结果如下:
[{"age":20,"name":"张三0","time":1616920360000},{"age":21,"name":"张三1","time":1616920360000},{"age":22,"name":"张三2","time":1616920360000},{"age":23,"name":"张三3","time":1616920360000},{"age":24,"name":"张三4","time":1616920360000},{"age":25,"name":"张三5","time":1616920360000},{"age":26,"name":"张三6","time":1616920360000},{"age":27,"name":"张三7","time":1616920360000},{"age":28,"name":"张三8","time":1616920360000},{"age":29,"name":"张三9","time":1616920360000}]
easyexcel 同样也支持自定义数据结构导出导入excel。
public static void main(String[] args) {
//表头
List<List<String>> headList = new ArrayList<>();
headList.add(Lists.newArrayList("姓名"));
headList.add(Lists.newArrayList("年龄"));
headList.add(Lists.newArrayList("操作时间"));
//数据体
List<List<Object>> dataList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
List<Object> data = new ArrayList<>();
data.add("张三" + i);
data.add(20 + i);
data.add(new Date(System.currentTimeMillis() + i));
dataList.add(data);
}
EasyExcel.write("/Users/hello/Documents/easyexcel-user2.xls").head(headList).sheet("用户信息").doWrite(dataList);
}
public static void main(String[] args) {
String filePath = "/Users/panzhi/Documents/easyexcel-user2.xls";
UserDataListener userDataListener = new UserDataListener();
EasyExcel.read(filePath, userDataListener).sheet().doRead();
System.out.println("表头:" + JSONArray.toJSONString(userDataListener.getHeadList()));
System.out.println("数据体:" + JSONArray.toJSONString(userDataListener.getDataList()));
}
运行程序,输出结果如下:
表头:[{0:"姓名",1:"年龄",2:"操作时间"}]
数据体:[{0:"张三0",1:"20",2:"2021-03-28 16:31:39"},{0:"张三1",1:"21",2:"2021-03-28 16:31:39"},{0:"张三2",1:"22",2:"2021-03-28 16:31:39"},{0:"张三3",1:"23",2:"2021-03-28 16:31:39"},{0:"张三4",1:"24",2:"2021-03-28 16:31:39"},{0:"张三5",1:"25",2:"2021-03-28 16:31:39"},{0:"张三6",1:"26",2:"2021-03-28 16:31:39"},{0:"张三7",1:"27",2:"2021-03-28 16:31:39"},{0:"张三8",1:"28",2:"2021-03-28 16:31:39"},{0:"张三9",1:"29",2:"2021-03-28 16:31:39"}]
更多的 api 操作可以访问 easyexcel - 接口文档
总体来说,easypoi和easyexcel都是基于apache poi进行二次开发的。
不同点在于:
1、easypoi 在读写数据的时候,优先是先将数据写入内存,优点是读写性能非常高,但是当数据量很大的时候,会出现oom,当然它也提供了 sax 模式的读写方式,需要调用特定的方法实现。
2、easyexcel 基于sax模式进行读写数据,不会出现oom情况,程序有过高并发场景的验证,因此程序运行比较稳定,相对于 easypoi 来说,读写性能稍慢!
easypoi 与 easyexcel 还有一点区别在于,easypoi 对定制化的导出支持非常的丰富,如果当前的项目需求,并发量不大、数据量也不大,但是需要导出 excel 的文件样式千差万别,那么我推荐你用 easypoi;反之,使用 easyexcel !
文章浏览阅读4.8k次。你的分析结果有T值,有sig值,说明你是在进行平均值的比较。也就是你在比较两组数据之间的平均值有没有差异。从具有t值来看,你是在进行T检验。T检验是平均值的比较方法。T检验分为三种方法:1.单一样本t检验(One-samplettest),是用来比较一组数据的平均值和一个数值有无差异。例如,你选取了5个人,测定了他们的身高,要看这五个人的身高平均值是否高于、低于还是等于1.70m,就需要用这个..._sig值计算公式
文章浏览阅读362次。首先你需要掌握GUI编程,事件处理,已经监听器,你就掌握Swing的知识就好了Swing框架,JFrame,JPanel,鼠标、键盘监听事件Java基础,面向对象,异常处理,集合,IO流网络编程,Socket通信线程知识,Java逻辑基础上述的技术点估计需要将JavaSE这块学完才能掌握,下面进入正题。这里呢,我把几个常见的小游戏列出来,如下图:象棋对战,带聊天五子棋对战,带聊天打字游戏对战音乐播..._五子棋程序判断落子位置
文章浏览阅读322次,点赞6次,收藏8次。【代码】杭电2041 超级楼梯。_超级楼梯 (杭电2041)比赛题目 题目统计 全部提交时间限制:c/c++ 1000ms,其他语言
文章浏览阅读1.6k次。写在前面数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented)、集成的(Integrated)、相对稳定的(Non-Volatile)、反映历史变化(Time Variant)的数据集合,用于支持管理决策(Decision Making Support)。近年来,随着大数据的应用不断深入,构建企业级数据仓库成为了企业进行精细化运营的一种趋势。从管理者的视角来看,数据仓库是赋能业务并辅助决策的一种工具,从开发者的视角来看,数据仓库是一堆数据模型的集合。数仓开发是一个系_从需求出发建设数仓会有什么问题
文章浏览阅读3.2k次。插入关键字 40 ,按照第 2 种情况将结点分裂,并将关键字 37 上移到父结点,发现父结点 [15、37、44、59] 包含的关键字的个数大于 M ,所以将结点 [15、37、44、59] 分裂为两个结点 [15、37] 和结点 [44、59] ,并将关键字 37 上移到父结点中 [37、59、97] . 父结点包含关键字个数没有超过 M ,插入结束。比如插入关键字 12 ,插入关键字所在的结点的 [10,15] 包含两个关键字,小于 M ,则直接插入关键字 12。B+树插入删除时间复杂度为0(1)_手写b+树
文章浏览阅读82次。在答辩过程中,要充分展示对项目的深入研究和对技术的理解,结合实际案例和数据,清晰阐述项目的创新、可行性和应用价值,回答评委问题时要有条理、准确表达自己的观点。管理员:首页、用户管理、管理员、员工、更多管理、部门管理、 请假申请、人事考勤、公司绩效、奖惩信息、通知公告、员工工资等。员工:首页、更多管理、请假申请、人事考勤、公司绩效、奖惩信息、通知公告、员工工资等。该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等。前端技术:JavaScript、VUE.js(2.X)、css3。_基于ssm的企业人力资源管理系统的设计与实现
文章浏览阅读4.7k次。先占个空,以后再详细拆解主要关注与GSM的区别,特别是GRPS是如何通过增加信道和分组交换系统支持数据传输,如何通过新的调制解调技术,增加数据传输的速率的!1. GSM是全球移动通讯系统(Global System for Mobile Communications)的简称2. GPRS是通用分组无线业务(General Packet Radio Service)的简称3. GPRS是在GSM系统基础上发展起来的分组数据承载和传输业务。4. GPRS与GSM......_2g slot
文章浏览阅读10w+次。图像拼接系列相关论文精读Seam Carving for Content-Aware Image ResizingAs-Rigid-As-Possible Shape ManipulationAdaptive As-Natural-As-Possible Image StitchingShape-Preserving Half-Projective Warps for Image StitchingSeam-Driven Image StitchingParallax-tolerant Ima_natural image stitching using depth maps
文章浏览阅读1.6w次,点赞131次,收藏52次。一、基本介绍Java泛型是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。二、提出背景Java集合(Collection)中元素的类型是多种多样的。例如,有些集合中的元素是Byte类型的,而有些则可能是String类型的,等等。Java允许程序员构建一个元素类型为Object的Collection,其中的元素可以是任何类型在Java S._java基础
文章浏览阅读1.7k次,点赞26次,收藏14次。vue中使用echarts实现省市地图绘制,根据数据在地图上显示柱状图信息;增加涟漪特效动画。本文以吉林省地图为例,来实现吉林省市的地图的绘制。根据数据在地图上显示柱状图信息;增加涟漪特效动画。你也可以显示中国地图或其他身份地图。原理是一样的哦。主要是通过geo地理坐标系组件实现地图绘制。柱状图是利用3个样式(顶部椭圆、中部矩形、底部椭圆)层叠实现的。_vue 市区地图+经纬度自定义显示弹窗详情
文章浏览阅读1.2k次,点赞46次,收藏20次。网络安全等级保护2.0自查表 | 技术部分_网络安全等级保护自查表
文章浏览阅读64次。已知一个iis漏洞可以让php解释任意的给定文件。挑战:怎么执行任意命令?应用环境:防火墙配置不准许对外连接。要求:不能要求上传文件。总算看到一次答案了:http://www.inbreak.net/kxlzxtest/phpiis.txtC:\Windows\System32\LogFiles\w3svcXXXX让php解析当天访问日志,然后用get请求提交user agent为 User-Ag..._php iis 漏洞