热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java如何导入和导出Excel文件的方法和步骤详解

本文详细介绍了在SpringBoot中使用Java导入和导出Excel文件的方法和步骤,包括添加操作Excel的依赖、自定义注解等。文章还提供了示例代码,并将代码上传至GitHub供访问。

前言

由于在最近的项目中使用Excel导入和导出较为频繁,以此篇博客作为记录,方便日后查阅。本文前台页面将使用layui,来演示对Excel文件导入和导出的效果。本文代码已上传至我的gitHub,欢迎访问,地址:https://github.com/rename123/excel-demo

准备工作

1. 添加操作Excel的有关依赖,如下:

org.apache.poi

poi

3.13

org.apache.poi

poi-ooxml

3.13

说明:由于我的项目是使用的maven管理,所以通过如上方式添加依赖,如果是通过gradle构建的项目,请按如下方式导入项目依赖:

implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'

2. 自定义注解,用来表示实体类中的属性在Excel中的标题、位置等

package com.reminis.exceldemo.annotation;

import java.lang.annotation.*;

/**

* 自定义实体类所需要的bean(Excel属性标题、位置等)

*/

@Target({ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface ExcelColumn {

/**

* Excel标题

* @return

*/

String value() default "";

/**

* Excel从左往右排列位置

* @return

*/

int col() default 0;

}

3. 编写ExcelUtils工具类

package com.reminis.exceldemo.util;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.math.BigDecimal;

import java.net.URLEncoder;

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Comparator;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.concurrent.atomic.AtomicInteger;

import java.util.stream.Collectors;

import java.util.stream.Stream;

import com.reminis.exceldemo.annotation.ExcelColumn;

import org.apache.commons.collections.CollectionUtils;

import org.apache.commons.lang.BooleanUtils;

import org.apache.commons.lang.CharUtils;

import org.apache.commons.lang.StringUtils;

import org.apache.commons.lang.math.NumberUtils;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.ss.usermodel.Cell;

import org.apache.poi.ss.usermodel.CellStyle;

import org.apache.poi.ss.usermodel.Font;

import org.apache.poi.ss.usermodel.IndexedColors;

import org.apache.poi.ss.usermodel.Row;

import org.apache.poi.ss.usermodel.Sheet;

import org.apache.poi.ss.usermodel.Workbook;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.http.MediaType;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class ExcelUtils {

private final static Logger log = LoggerFactory.getLogger(ExcelUtils.class);

private final static String EXCEL2003 = "xls";

private final static String EXCEL2007 = "xlsx";

public static List readExcel(String path, Class cls, MultipartFile file){

String fileName = file.getOriginalFilename();

if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {

log.error("上传文件格式不正确");

}

List dataList &#61; new ArrayList<>();

Workbook workbook &#61; null;

try {

InputStream is &#61; file.getInputStream();

if (fileName.endsWith(EXCEL2007)) {

// FileInputStream is &#61; new FileInputStream(new File(path));

workbook &#61; new XSSFWorkbook(is);

}

if (fileName.endsWith(EXCEL2003)) {

// FileInputStream is &#61; new FileInputStream(new File(path));

workbook &#61; new HSSFWorkbook(is);

}

if (workbook !&#61; null) {

//类映射 注解 value-->bean columns

Map> classMap &#61; new HashMap<>();

List fields &#61; Stream.of(cls.getDeclaredFields()).collect(Collectors.toList());

fields.forEach(

field -> {

ExcelColumn annotation &#61; field.getAnnotation(ExcelColumn.class);

if (annotation !&#61; null) {

String value &#61; annotation.value();

if (StringUtils.isBlank(value)) {

return;//return起到的作用和continue是相同的 语法

}

if (!classMap.containsKey(value)) {

classMap.put(value, new ArrayList<>());

}

field.setAccessible(true);

classMap.get(value).add(field);

}

}

);

//索引-->columns

Map> reflectionMap &#61; new HashMap<>(16);

//默认读取第一个sheet

Sheet sheet &#61; workbook.getSheetAt(0);

boolean firstRow &#61; true;

for (int i &#61; sheet.getFirstRowNum(); i <&#61; sheet.getLastRowNum(); i&#43;&#43;) {

Row row &#61; sheet.getRow(i);

//首行 提取注解

if (firstRow) {

for (int j &#61; row.getFirstCellNum(); j <&#61; row.getLastCellNum(); j&#43;&#43;) {

Cell cell &#61; row.getCell(j);

String cellValue &#61; getCellValue(cell);

if (classMap.containsKey(cellValue)) {

reflectionMap.put(j, classMap.get(cellValue));

}

}

firstRow &#61; false;

} else {

//忽略空白行

if (row &#61;&#61; null) {

continue;

}

try {

T t &#61; cls.newInstance();

//判断是否为空白行

boolean allBlank &#61; true;

for (int j &#61; row.getFirstCellNum(); j <&#61; row.getLastCellNum(); j&#43;&#43;) {

if (reflectionMap.containsKey(j)) {

Cell cell &#61; row.getCell(j);

String cellValue &#61; getCellValue(cell);

if (StringUtils.isNotBlank(cellValue)) {

allBlank &#61; false;

}

List fieldList &#61; reflectionMap.get(j);

fieldList.forEach(

x -> {

try {

handleField(t, cellValue, x);

} catch (Exception e) {

log.error(String.format("reflect field:%s value:%s exception!", x.getName(), cellValue), e);

}

}

);

}

}

if (!allBlank) {

dataList.add(t);

} else {

log.warn(String.format("row:%s is blank ignore!", i));

}

} catch (Exception e) {

log.error(String.format("parse row:%s exception!", i), e);

}

}

}

}

} catch (Exception e) {

log.error(String.format("parse excel exception!"), e);

} finally {

if (workbook !&#61; null) {

try {

workbook.close();

} catch (Exception e) {

log.error(String.format("parse excel exception!"), e);

}

}

}

return dataList;

}

private static void handleField(T t, String value, Field field) throws Exception {

Class> type &#61; field.getType();

if (type &#61;&#61; null || type &#61;&#61; void.class || StringUtils.isBlank(value)) {

return;

}

if (type &#61;&#61; Object.class) {

field.set(t, value);

//数字类型

} else if (type.getSuperclass() &#61;&#61; null || type.getSuperclass() &#61;&#61; Number.class) {

if (type &#61;&#61; int.class || type &#61;&#61; Integer.class) {

field.set(t, NumberUtils.toInt(value));

} else if (type &#61;&#61; long.class || type &#61;&#61; Long.class) {

field.set(t, NumberUtils.toLong(value));

} else if (type &#61;&#61; byte.class || type &#61;&#61; Byte.class) {

field.set(t, NumberUtils.toByte(value));

} else if (type &#61;&#61; short.class || type &#61;&#61; Short.class) {

field.set(t, NumberUtils.toShort(value));

} else if (type &#61;&#61; double.class || type &#61;&#61; Double.class) {

field.set(t, NumberUtils.toDouble(value));

} else if (type &#61;&#61; float.class || type &#61;&#61; Float.class) {

field.set(t, NumberUtils.toFloat(value));

} else if (type &#61;&#61; char.class || type &#61;&#61; Character.class) {

field.set(t, CharUtils.toChar(value));

} else if (type &#61;&#61; boolean.class) {

field.set(t, BooleanUtils.toBoolean(value));

} else if (type &#61;&#61; BigDecimal.class) {

field.set(t, new BigDecimal(value));

}

} else if (type &#61;&#61; Boolean.class) {

field.set(t, BooleanUtils.toBoolean(value));

} else if (type &#61;&#61; Date.class) {

//

field.set(t, value);

} else if (type &#61;&#61; String.class) {

field.set(t, value);

} else if (type &#61;&#61; LocalDateTime.class) {

//String 转 LocalDateTime

DateTimeFormatter df &#61; DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

LocalDateTime dt &#61; LocalDateTime.parse(value, df);

field.set(t, dt);

} else {

Constructor> constructor &#61; type.getConstructor(String.class);

field.set(t, constructor.newInstance(value));

}

}

private static String getCellValue(Cell cell) {

if (cell &#61;&#61; null) {

return "";

}

if (cell.getCellType() &#61;&#61; Cell.CELL_TYPE_NUMERIC) {

if (HSSFDateUtil.isCellDateFormatted(cell)) {

return HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toString();

} else {

return new BigDecimal(cell.getNumericCellValue()).toString();

}

} else if (cell.getCellType() &#61;&#61; Cell.CELL_TYPE_STRING) {

return StringUtils.trimToEmpty(cell.getStringCellValue());

} else if (cell.getCellType() &#61;&#61; Cell.CELL_TYPE_FORMULA) {

return StringUtils.trimToEmpty(cell.getCellFormula());

} else if (cell.getCellType() &#61;&#61; Cell.CELL_TYPE_BLANK) {

return "";

} else if (cell.getCellType() &#61;&#61; Cell.CELL_TYPE_BOOLEAN) {

return String.valueOf(cell.getBooleanCellValue());

} else if (cell.getCellType() &#61;&#61; Cell.CELL_TYPE_ERROR) {

return "ERROR";

} else {

return cell.toString().trim();

}

}

public static void writeExcel(HttpServletRequest request, HttpServletResponse response, List dataList, Class cls){

Field[] fields &#61; cls.getDeclaredFields();

List fieldList &#61; Arrays.stream(fields)

.filter(field -> {

ExcelColumn annotation &#61; field.getAnnotation(ExcelColumn.class);

if (annotation !&#61; null && annotation.col() > 0) {

field.setAccessible(true);

return true;

}

return false;

}).sorted(Comparator.comparing(field -> {

int col &#61; 0;

ExcelColumn annotation &#61; field.getAnnotation(ExcelColumn.class);

if (annotation !&#61; null) {

col &#61; annotation.col();

}

return col;

})).collect(Collectors.toList());

Workbook wb &#61; new XSSFWorkbook();

Sheet sheet &#61; wb.createSheet("Sheet1");

AtomicInteger ai &#61; new AtomicInteger();

{

Row row &#61; sheet.createRow(ai.getAndIncrement());

AtomicInteger aj &#61; new AtomicInteger();

//写入头部

fieldList.forEach(field -> {

ExcelColumn annotation &#61; field.getAnnotation(ExcelColumn.class);

String columnName &#61; "";

if (annotation !&#61; null) {

columnName &#61; annotation.value();

}

Cell cell &#61; row.createCell(aj.getAndIncrement());

CellStyle cellStyle &#61; wb.createCellStyle();

cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());

cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);

cellStyle.setAlignment(CellStyle.ALIGN_CENTER);

Font font &#61; wb.createFont();

font.setBoldweight(Font.BOLDWEIGHT_NORMAL);

cellStyle.setFont(font);

cell.setCellStyle(cellStyle);

cell.setCellValue(columnName);

});

}

if (CollectionUtils.isNotEmpty(dataList)) {

dataList.forEach(t -> {

Row row1 &#61; sheet.createRow(ai.getAndIncrement());

AtomicInteger aj &#61; new AtomicInteger();

fieldList.forEach(field -> {

Class> type &#61; field.getType();

Object value &#61; "";

try {

value &#61; field.get(t);

} catch (Exception e) {

e.printStackTrace();

}

Cell cell &#61; row1.createCell(aj.getAndIncrement());

if (value !&#61; null) {

if (type &#61;&#61; Date.class) {

cell.setCellValue(value.toString());

} else if (type &#61;&#61; LocalDateTime.class){

DateTimeFormatter df &#61; DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

cell.setCellValue(df.format((LocalDateTime) value));

} else {

cell.setCellValue(value.toString());

}

}

});

});

}

//冻结窗格

wb.getSheet("Sheet1").createFreezePane(0, 1, 0, 1);

//浏览器下载excel

buildExcelDocument(request.getParameter("fileName"),wb,response);

//生成excel文件

// buildExcelFile(".\\default.xlsx",wb);

}

/**

* 浏览器下载excel

* &#64;param fileName

* &#64;param wb

* &#64;param response

*/

private static void buildExcelDocument(String fileName, Workbook wb, HttpServletResponse response){

try {

response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

response.setHeader("Content-Disposition", "attachment;filename&#61;"&#43;URLEncoder.encode(fileName, "utf-8"));

response.flushBuffer();

ServletOutputStream outputStream &#61; response.getOutputStream();

wb.write(outputStream);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 生成excel文件

* &#64;param path 生成excel路径

* &#64;param wb

*/

private static void buildExcelFile(String path, Workbook wb){

File file &#61; new File(path);

if (file.exists()) {

file.delete();

}

try {

wb.write(new FileOutputStream(file));

} catch (Exception e) {

e.printStackTrace();

}

}

}

4. 定义需要导出的实体类

package com.reminis.exceldemo.entity;

import com.reminis.exceldemo.annotation.ExcelColumn;

import lombok.Data;

import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;

import java.time.LocalDateTime;

import java.util.Date;

&#64;Data

public class Emp {

&#64;ExcelColumn(value &#61; "员工主键id", col &#61; 1)

private Integer id;

&#64;ExcelColumn(value &#61; "员工编号",col &#61; 2)

private String empNo;

&#64;ExcelColumn(value &#61; "员工名称",col &#61; 3)

private String empName;

&#64;ExcelColumn(value &#61; "员工薪资",col &#61; 4)

private BigDecimal salary;

&#64;ExcelColumn(value &#61; "员工职称",col &#61; 5)

private String job;

&#64;ExcelColumn(value &#61; "入职时间",col &#61; 6)

private LocalDateTime entryTime;

}

Controller层编写

在我们做完准备工作后&#xff0c;就可以在我们的Controller层编写访问接口了&#xff0c;由于我们没有连接数据库&#xff0c;所以我准备了一些测试数据&#xff0c;具体代码如下&#xff1a;

package com.reminis.exceldemo.web;

import com.alibaba.fastjson.JSON;

import com.reminis.exceldemo.entity.Emp;

import com.reminis.exceldemo.util.ExcelUtils;

import com.reminis.exceldemo.util.Result;

import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.Logger;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.math.BigDecimal;

import java.time.LocalDateTime;

import java.util.ArrayList;

import java.util.List;

&#64;CrossOrigin("*")

&#64;RestController

&#64;RequestMapping("/api/test")

public class ExcelController {

private static final Logger log &#61; LogManager.getLogger(ExcelController.class);

/**

* Excel导出

* &#64;param response

*/

&#64;GetMapping("/exportExcel")

public void exportExcel(HttpServletRequest request,HttpServletResponse response){

//使用假数据代替从数据库查出来的需要导出的数据

List empList &#61; handleRepositoryData();

long t1 &#61; System.currentTimeMillis();

ExcelUtils.writeExcel(request,response, empList, Emp.class);

long t2 &#61; System.currentTimeMillis();

System.out.println(String.format("write over! cost:%sms", (t2 - t1)));

}

/**

* Excel导入

* &#64;param file

*/

&#64;PostMapping("/readExcel")

public Result readExcel(&#64;RequestBody MultipartFile file){

long t1 &#61; System.currentTimeMillis();

log.info("上传的文件&#xff1a;"&#43;file);

List list &#61; ExcelUtils.readExcel("", Emp.class, file);

long t2 &#61; System.currentTimeMillis();

System.out.println(String.format("read over! cost:%sms", (t2 - t1)));

list.forEach(

b -> System.out.println(JSON.toJSONString(b))

);

return new Result<>();

}

public List handleRepositoryData() {

List empList &#61; new ArrayList<>();

Emp emp;

for (int i &#61; 1; i<&#61; 10; i&#43;&#43;) {

emp &#61; new Emp();

emp.setId(i);

emp.setEmpName("员工" &#43; i);

emp.setEmpNo((1000 &#43; i) &#43; "");

emp.setJob("JY" &#43; i);

emp.setSalary(new BigDecimal(i * 1000 &#43; ""));

emp.setEntryTime(LocalDateTime.now().minusHours(Long.valueOf(i)));

empList.add(emp);

}

return empList;

}

/**

* 前台页面的数据列表

* &#64;return

*/

&#64;GetMapping("/getList")

public Result getList(){

Result> result &#61; new Result<>();

List empList &#61; handleRepositoryData();

result.setData(empList);

return result;

}

}

关于Excel导入导出功能的后台接口&#xff0c;到这里就写好了。由于本文示例代码中使用了Java8中的新时间&#xff0c;所以在将数据返回给前台页面时&#xff0c;我们需要对时间格式进行处理&#xff0c;如下&#xff1a;

package com.reminis.exceldemo.config;

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;

&#64;Configuration

public class LocalDateTimeSerializerConfig {

&#64;Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")

private String pattern;

&#64;Bean

public LocalDateTimeSerializer localDateTimeDeserializer() {

return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));

}

&#64;Bean

public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {

return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());

}

}

最后就是layui展示页面了&#xff0c;是一个很简单上传下载的列表页面&#xff0c;代码如下&#xff1a;

Excel文件的导入导出测试

Excel文件的导入导出测试

导入Excel 

后台接口导出Excel

layui导出选中行的数据

//一般直接写在一个js文件中

layui.use([&#39;table&#39;, &#39;layer&#39;,&#39;upload&#39;], function(){

var table &#61; layui.table

,$ &#61; layui.$

,layer &#61; layui.layer

,upload &#61; layui.upload;

// layer.msg(&#39;Hello World&#39;);

var ins1 &#61; table.render({

elem: &#39;#test&#39;

,url:&#39;http://localhost:8080/api/test/getList&#39;

,cols: [[

{type:&#39;checkbox&#39;}

,{field:&#39;id&#39;, title: &#39;ID&#39;, sort: true}

,{field:&#39;empNo&#39;,title: &#39;员工编号&#39;}

,{field:&#39;empName&#39;,title: &#39;员工名称&#39;}

,{field:&#39;salary&#39;, title: &#39;薪资&#39;}

,{field:&#39;job&#39;, title: &#39;职称&#39;} //minWidth&#xff1a;局部定义当前单元格的最小宽度&#xff0c;layui 2.2.1 新增

,{field:&#39;entryTime&#39;, title: &#39;入职时间&#39;}

]]

});

//指定允许上传的文件类型

upload.render({

elem: &#39;#test3&#39;

,url: &#39;http://localhost:8080/api/test/readExcel&#39; //改成您自己的上传接口

,accept: &#39;file&#39; //普通文件

,done: function(res){

layer.msg(&#39;上传成功&#39;);

console.log(res);

}

});

//Excel后台导出

$("#test4").click(function () {

// 文件名称可以根据自己需要进行设置

window.open(&#39;http://localhost:8080/api/test/exportExcel?fileName&#61;员工表导出测试.xlsx&#39;)

})

//Excel通过layui导出

$("#test5").click(function () {

// console.log("123")

var checkStatus &#61; table.checkStatus(&#39;test&#39;); //test 即为table绑定的id

//获取选中行的数据

var data &#61; checkStatus.data;

//将上述表格示例中的指定数据导出为 Excel 文件

table.exportFile(ins1.config.id, data); //data 为该实例中的任意数量的数据

})

});

由于博客园还不支持上传视频&#xff0c;我就放几张运行的效果图吧&#xff0c;本文代码也已经上传至gitHub&#xff0c;本文有些代码没有写出来&#xff0c;可以到gitHub上把代码拉下来进行测试&#xff1a;

9e2a3751e2c7c35b63d61b9a0dd1f2fa.png

因为本文只是对excel的导入和导出进行测试&#xff0c;并没有来连接数据进行入库操作&#xff0c;但在导入Excel这个接口中&#xff0c;我已经获取到了导入的数据&#xff0c;并在控制台打印了出来&#xff0c;如下&#xff1a;

49c8e624ca3627d75176c34bb11c76ce.png



推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
author-avatar
骑猪猪-逛恋空
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有