导出excel通用模板(程序定义模板导出)

转载原文:https://www.jianshu.com/p/5c7b359a159c

如下代码,本方法主要用于程序定义模板格式,并导出文件。该方法将定义和创建分离,达到了一定解耦合,降低了开发复杂度。但是依然是程序定义模板,对模板的样式需要程序控制,没有达到将数据和样式分离的目的。

改良版,关于添加依赖之类的之前一篇文章里面有。
这篇是把之前的方法抽成通用模板。

一、添加一个实体类

package com.lencity.securitymanagementplatform.data.entity;

import java.util.List;

public class XlsData {

    public static final int DATA_TYPE_INTEGER = 0;
public static final int DATA_TYPE_STRING = 1;
private List<String> titles;//表头
private List<Integer> types;//数据类型
private List<List<Object>> values;存表数据 public List<Integer> getTypes() {
return types;
}
public void setTypes(List<Integer> types) {
this.types = types;
}
public List<String> getTitles() {
return titles;
}
public void setTitles(List<String> titles) {
this.titles = titles;
}
public List<List<Object>> getValues() {
return values;
}
public void setValues(List<List<Object>> values) {
this.values = values;
}
}

二、创建一个service类

package com.lencity.securitymanagementplatform.service;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.stereotype.Service; import com.lencity.securitymanagementplatform.data.entity.XlsData; @Service
public class XlsService { //写一个接口,哪个控制器需要加上导出excel功能就继承这个接口
public static interface IXlsOutputProcessor {
public XlsData processXlsData(Map<String, Object> condition);
} //解析数据创建excel
public HSSFWorkbook createExcelData(IXlsOutputProcessor processor, Map<String, Object> condition) {
XlsData xlsData = processor.processXlsData(condition);
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("统计表");// 创建一个excel表单
HSSFRow titleRow = sheet.createRow(0);
// 设置列宽,setColumnWidth的第二个参数要乘以256,这个参数的单位是1/256个字符宽度
sheet.setColumnWidth(1, 15 * 256);
sheet.setColumnWidth(3, 20 * 256); HSSFCellStyle style = workbook.createCellStyle();
style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));// 设置日期格式
HSSFFont font = workbook.createFont();// 设置为居中加粗
font.setBold(true);
style.setAlignment(HorizontalAlignment.CENTER);
style.setFont(font);
List<String> titles = xlsData.getTitles();
HSSFCell cell;
/* 构造表头 */
for (int i = 0; i < titles.size(); i++) {
cell = titleRow.createCell(i);
cell.setCellValue(titles.get(i));
cell.setCellStyle(style);
}
int rowNum = 1;
List<Integer> dataTypes = xlsData.getTypes();
List<List<Object>> values = xlsData.getValues();
for (int i = 0; i < values.size(); i++) {
List<Object> value = values.get(i);
HSSFRow row = sheet.createRow(rowNum);
for (int j = 0; j < value.size(); j++) {
switch (dataTypes.get(j)) {
case XlsData.DATA_TYPE_INTEGER:
row.createCell(j).setCellValue((Integer) value.get(j));
break;
case XlsData.DATA_TYPE_STRING:
row.createCell(j).setCellValue((String) value.get(j));
break;
}
}
rowNum++; }
return workbook;
} // 浏览器导出excel
public void buildExcelDocument(String filename, HSSFWorkbook workbook, HttpServletResponse response)
throws Exception {
response.reset();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf-8"));
OutputStream outputStream = response.getOutputStream();
workbook.write(outputStream);
outputStream.flush();
outputStream.close();
} // 下载excel模板功能
public void downloadTemplate(HttpServletResponse response,HttpServletRequest request) throws Exception {
String fileName="导出模板.xls";
response.reset();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
String filePath=request.getServletContext().getRealPath("/excel/")+fileName;
FileInputStream input=new FileInputStream(filePath);
OutputStream out=response.getOutputStream();
byte[] b=new byte[2048];
int len;
while((len=input.read(b))!=-1) {
out.write(b,0,len);
}
response.setHeader("Content-Length", String.valueOf(input.getChannel().size()));
input.close();
}
}

三、控制器
假设我们要在用户页面加上导出表格的功能,那就在用户的控制器上继承接口

public class UserController implements IXlsOutputProcessor {

继承之后需要在控制器中重写接口方法,

 
导出的表格样式.png
关于封装数据,主要就是根据自己实际的项目需求,来构造数据了
// 封装数据
@Override
public XlsData processXlsData(Map<String, Object> condition) {
List<String> titles = new ArrayList<>();//表头
List<Integer> dataTypes = new ArrayList<>();//表数据类型
List<List<Object>> values = new ArrayList<>();//表头对应的数据
titles.add("姓名");
dataTypes.add(XlsData.DATA_TYPE_STRING);
titles.add("手机号码");
dataTypes.add(XlsData.DATA_TYPE_STRING);
titles.add("职位");
dataTypes.add(XlsData.DATA_TYPE_STRING);
titles.add("部门");
dataTypes.add(XlsData.DATA_TYPE_STRING);
List<User> users = userService.getUsersByCondition(condition);
XlsData xlsData = new XlsData();
xlsData.setTitles(titles);
xlsData.setTypes(dataTypes);
for (User user : users) {
List<Object> tmpList = new ArrayList<>();
tmpList.add(user.getName());
tmpList.add(user.getMobile());
tmpList.add(user.getPosition());
tmpList.add(departmentService.getDepartmentNameByDepartmentCode(user.getDepartmentCode()));
values.add(tmpList);
}
xlsData.setValues(values);
return xlsData;
} // 导出excel,前台js,点击 导出excel 关联的路径就是这个
@PostMapping(value = "/downLoadXls")
@ResponseBody
public String downLoadXls(Map<String, Object> condition, HttpServletResponse response) throws Exception {
String fileName = "导出excel.xls";
HSSFWorkbook workbook = xlsService.createExcelData(this, condition);
xlsService.buildExcelDocument(fileName, workbook, response);
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", 1);
return jsonObject.toString();
}
// 下载模板,前台js,点击 下载模板 关联的路径就是这个
@PostMapping(value = "/downloadTemplate")
@ResponseBody
public String downloadTemplate(HttpServletResponse response,HttpServletRequest request) throws Exception {
String fileName = "导出excel.xls";
xlsService.downloadTemplate(response, request);
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", 1);
return jsonObject.toString();
}
 
前台界面.png
 
模板的存放位置

前台按钮代码

<button type="button" class="btn btn-primary waves-effect" onclick="downloadTemplate()" id="downloadTemplate">
<i class="material-icons">vertical_align_bottom</i>
<span>下载模板</span>
</button> <button type="button" class="btn btn-primary waves-effect"onclick="exportExcel()">
<i class="material-icons">vertical_align_bottom</i>
<span>导出表格</span>
</button>

js

form表单里面是页面的表单筛选条件,如果要导数据库所有的数据,可把form表单去掉。如果导出的数据是有筛选条件的,需要改一下form表单
function exportExcel() {
var name = $("#name").val();
var departmentCode = $("#departmentCode").find("option:selected").val();
var form = $("<form>");
$('body').append(form);
form.attr('style','display:none');
form.attr('target','');
form.attr('method','post');
form.attr('action',contextPath+'/user/downLoadXls');//下载文件的请求路径 //对应查询条件的开始时间
var input1 = $('<input>');
input1.attr('type','hidden');
input1.attr('name',"name");
input1.attr('value',name);
form.append(input1); //对应查询条件的结束时间
var input2 = $('<input>');
input2.attr('type','hidden');
input2.attr('name','departmentCode');
input2.attr('value',departmentCode);
form.append(input2);
form.submit();
}
下载模板的js

function downloadTemplate() {
var form = $("<form>");
$('body').append(form);
form.attr('style', 'display:none');
form.attr('target', '');
form.attr('method', 'post');
form.attr('action', contextPath + '/user/downloadTemplate');// 下载文件的请求路径
form.submit();
}

二、java通过poi模板导出excel(程序根据模板样式导出

此方法与上文不同的是,用户自定义模板样式,程序根据参数名称和sheet名称来查找填写相应内容。

附上poi的maven配置:

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>

我使用了最新的版本。

package com.unionpay.cqupay.utils;

import com.unionpay.cqupay.common.CetcBigDataException;
import com.unionpay.cqupay.entity.SheetData;
import com.unionpay.cqupay.pojo.UmUserGatherPojo;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.*;
import java.util.Date;
import java.util.Iterator;
import java.util.List; /**
* @author adam
* @version 1.0
* @date 2019-9-23
*/
public class ExcelUtil {
private final static Logger logger = LoggerFactory.getLogger(ExcelUtil.class); /**
* Sheet复制
* @param fromSheet
* @param toSheet
* @param copyValueFlag
*/
public static void copySheet(Workbook wb, Sheet fromSheet, Sheet toSheet,
boolean copyValueFlag) {
//合并区域处理 mergerRegion(fromSheet, toSheet);
int index = 0;
for (Iterator<Row> rowIt = fromSheet.rowIterator(); rowIt.hasNext();) {
Row tmpRow = rowIt.next();
Row newRow = toSheet.createRow(tmpRow.getRowNum()); CellStyle style = tmpRow.getRowStyle();
if(style != null)
newRow.setRowStyle(tmpRow.getRowStyle()); newRow.setHeight(tmpRow.getHeight()); //针对第一行设置行宽
if(index == 0) {
int first = tmpRow.getFirstCellNum();
int last = tmpRow.getLastCellNum();
for(int i = first ; i < last ; i++) {
int w = fromSheet.getColumnWidth(i);
toSheet.setColumnWidth(i, w + 1);
}
toSheet.setDefaultColumnWidth(fromSheet.getDefaultColumnWidth());
} //行复制
copyRow(wb,tmpRow,newRow,copyValueFlag); index++ ;
}
}
/**
* 行复制功能
* @param fromRow
* @param toRow
*/
static void copyRow(Workbook wb,Row fromRow,Row toRow,boolean copyValueFlag){
for (Iterator<Cell> cellIt = fromRow.cellIterator(); cellIt.hasNext();) {
Cell tmpCell = cellIt.next();
Cell newCell = toRow.createCell(tmpCell.getColumnIndex());
copyCell(wb,tmpCell, newCell, copyValueFlag);
}
}
/**
* 复制原有sheet的合并单元格到新创建的sheet
*
* @param fromSheet 新创建sheet
* @param toSheet 原有的sheet
*/
static void mergerRegion(Sheet fromSheet, Sheet toSheet) {
int sheetMergerCount = fromSheet.getNumMergedRegions();
for (int i = 0; i < sheetMergerCount; i++) { CellRangeAddress cra = fromSheet.getMergedRegion(i); toSheet.addMergedRegion(cra);
}
}
/**
* 复制单元格
*
* @param srcCell
* @param distCell
* @param copyValueFlag
* true则连同cell的内容一起复制
*/
public static void copyCell(Workbook wb,Cell srcCell, Cell distCell,
boolean copyValueFlag) { CellStyle newstyle=wb.createCellStyle();
//copyCellStyle(srcCell.getCellStyle(), newstyle);
//distCell.setEncoding(srcCell.);
newstyle.cloneStyleFrom(srcCell.getCellStyle());
//样式
distCell.setCellStyle(newstyle);
//评论
if (srcCell.getCellComment() != null) {
distCell.setCellComment(srcCell.getCellComment());
}
// 不同数据类型处理
CellType srcCellType = srcCell.getCellTypeEnum();
distCell.setCellType(srcCellType); if (copyValueFlag) {
if (srcCellType == CellType.NUMERIC) {
if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(srcCell)) {
distCell.setCellValue(srcCell.getDateCellValue());
} else {
distCell.setCellValue(srcCell.getNumericCellValue());
}
} else if (srcCellType == CellType.STRING ) {
distCell.setCellValue(srcCell.getRichStringCellValue());
} else if (srcCellType == CellType.BLANK ) {
// nothing21
} else if (srcCellType == CellType.BOOLEAN ) {
distCell.setCellValue(srcCell.getBooleanCellValue());
} else if (srcCellType == CellType.ERROR ) {
distCell.setCellErrorValue(srcCell.getErrorCellValue()); } else if (srcCellType == CellType.FORMULA ) {
distCell.setCellFormula(srcCell.getCellFormula());
} else { // nothing29
}
}
} /**
* 写入excel数据
* @param model 采用的模板 位置在 src/model/下 模板第一个sheet页必须是模板sheet
* @param sheetDatas 模板数据
*/ public static void writeData(String model , OutputStream out, SheetData... sheetDatas ) { Workbook wb = null;
try {
InputStream input = new FileInputStream(model);
// InputStream input = ExcelUtils2.class.getResourceAsStream(model);
if(input == null) {
throw new RuntimeException("模板文件不存在"+model);
} if(model.endsWith(".xlsx"))
wb = new XSSFWorkbook(input);
else if(model.endsWith(".xls"))
wb = new HSSFWorkbook(input);
else
throw new RuntimeException("模板文件不合法,不是excel类型"+model );
} catch (IOException e) {
//e.printStackTrace(); throw new RuntimeException("加载模板文件失败"+model);
} Sheet source = wb.getSheetAt(0); //就一个的话 直接用模板
int size = sheetDatas.length ;
/*for(int i = 0 ; i < size ; i++) { if(i == 0) {
if (sheetDatas[0]!=null){
wb.setSheetName(0, sheetDatas[0].getName());
} } else {
if (sheetDatas[i]!=null) {
Sheet toSheet = wb.createSheet(sheetDatas[i].getName());
//复制格式
copySheet(wb, source, toSheet, true);
} } }*/
int numberOfSheets=wb.getNumberOfSheets();
out:for(int i = 0 ; i < size ; i++) {
String sheetDatasName=sheetDatas[i].getName();
if (StringUtils.isNotBlank(sheetDatasName)){
for(int j=0;j<numberOfSheets;j++){
if (sheetDatasName.equals(wb.getSheetAt(j).getSheetName())){
//写数据
writeData(sheetDatas[i],wb.getSheetAt(j) );
continue out;
}
}
} }
try {
wb.write(out);
out.flush();
wb.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
} } /**
* 向sheet页中写入数据
* @param sheetData 数据Map
* @param sheet sheet
*/
public static void writeData(SheetData sheetData , Sheet sheet) { //从sheet中找到匹配符 #{}表示单个 , ${}表示集合,从该单元格开始向下追加 for(Iterator<Row> rowIt = sheet.rowIterator(); rowIt.hasNext();) {
Row row = rowIt.next();
//取cell
for(int j = row.getFirstCellNum() ; j < row.getLastCellNum() ; j++) { Cell cell = row.getCell(j); //判断cell的内容是否包含 $ 或者#
if(cell != null && cell.getCellTypeEnum() == CellType.STRING && cell.getStringCellValue() != null
&& (cell.getStringCellValue().contains("$") || cell.getStringCellValue().contains("#") )) {
//剥离# $
String[] winds = CommonUtils.getWildcard(cell.getStringCellValue().trim()); for(String wind : winds) { writeData(sheetData, wind , cell , sheet);
} } } }
} /**
* 填充数据
* @param sheetData
* @param keyWind #{name}只替换当前 or ${names} 从当前行开始向下替换
*/
static void writeData(SheetData sheetData , String keyWind , Cell cell , Sheet sheet) {
String key = keyWind.substring(2 , keyWind.length() - 1); if(keyWind.startsWith("#")) { //简单替换 Object value = sheetData.get(key);
//为空则替换为空字符串
if(value == null)
value = "" ; String cellValue = cell.getStringCellValue();
cellValue = cellValue.replace(keyWind, value.toString()); cell.setCellValue(cellValue); } else if(keyWind.startsWith("$")) { //从list中每个实体开始解,行数从当前开始
int rowindex = cell.getRowIndex();
int columnindex = cell.getColumnIndex(); List<? extends Object> listdata = sheetData.getDatas(); //不为空的时候开始填充
if(listdata != null && !listdata.isEmpty()){
for(Object o : listdata) {
Object cellValue = CommonUtils.getValue(o, key); Row row = sheet.getRow(rowindex);
if(row == null) {
row = sheet.createRow(rowindex);
} //取出cell
Cell c = row.getCell(columnindex);
if(c == null)
c = row.createCell(columnindex);
if(cell.getCellStyle() != null){
c.setCellStyle(cell.getCellStyle()); } if(cell.getCellTypeEnum() != null) {
c.setCellType(cell.getCellTypeEnum()); } if(cellValue != null) {
if(cellValue instanceof Number || CommonUtils.isNumber(cellValue) )
c.setCellValue( Double.valueOf(cellValue.toString()));
else if(cellValue instanceof Boolean)
c.setCellValue((Boolean)cellValue);
else if(cellValue instanceof Date)
c.setCellValue(DateUtil.getDayFormatStr((Date)cellValue,sheetData.getTimeFormat()));
else
c.setCellValue(cellValue.toString());
} else { //数据为空 如果当前单元格已经有数据则重置为空
if(c.getStringCellValue() != null) {
c.setCellValue("");
} } rowindex++ ;
}
} else {
//list数据为空则将$全部替换空字符串
String cellValue = "" ; cell.setCellValue(cellValue); } } } public static File createFile(String templateName,String fileName, SheetData... sheetData) throws CetcBigDataException {
String model = System.getProperty("user.dir")+File.separator+"res"+File.separator+"model"+File.separator+templateName ; //创建个临时文件
File file=new File("temp"+File.separator+"statistics");
if(!file.exists()){//如果文件夹不存在
file.mkdirs();//创建文件夹
}
file=new File("temp"+File.separator+"statistics"+File.separator+fileName); try {
TemplateExcelUtil.writeData(model, new FileOutputStream(file), sheetData);
}catch (Exception e){
throw new CetcBigDataException("导出表格失败,失败原因:"+e.getMessage()); }
return file; } public static void main(String[] args) { //获取模板
// logger.info("项目路径{}",System.getProperty("user.dir")); // String model = System.getProperty("user.dir")+File.separator+"res\\model\\template_user.xlsx" ;
String model = "D:\\cetc\\nas\\cetcData\\excelmodel\\template_user.xlsx" ;
File f = new File("e:/test.xlsx"); SheetData sd = new SheetData("用户统计");
sd.put("name", "张三");
sd.put("age", 13); //每个sheet页加入100条测试数据
//注意这里可以加入pojo也可以直接使用map,理论上map在这里效率更高一些
UmUserGatherPojo vo=new UmUserGatherPojo();
vo.setMonth("201909");
vo.setUserRegisterNum(100);
vo.setUserActiveNum(65);
sd.addData(vo);
UmUserGatherPojo vo2=new UmUserGatherPojo();
vo2.setMonth("201908");
vo2.setUserRegisterNum(90);
vo2.setUserActiveNum(null);
sd.addData(vo2); try {
      ExcelUtils.writeData(model, new FileOutputStream(f) ,sd);
        } catch (FileNotFoundException e) {
e.printStackTrace();
} }
}
package com.unionpay.cqupay.entity;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map; /**
* @author adam
* @version 1.0
* @date 2019-9-23
*/
public class SheetData { /**
* sheet页中存储 #{key} 的数据
*/
private Map<String, Object> map = new HashMap<String, Object>(); /**
* 列表数据存储 sheet页中替换${key} 并以列为单位向下赋值
*/
private List<Object> datas = new LinkedList<Object>(); private String name ;
private String timeFormat; public void setName(String name) {
this.name = name;
} public String getName() {
return name;
} public String getTimeFormat() {
return timeFormat;
} public void setTimeFormat(String timeFormat) {
this.timeFormat = timeFormat;
} public SheetData(String name) {
super();
this.name = name;
} public SheetData(String name,String timeFormat) {
super();
this.name = name;
this.timeFormat=timeFormat;
}
public void put(String key , Object value) {
map.put(key, value);
} public void remove(String key) {
map.remove(key);
} public Object get(String key) {
return map.get(key);
} /**
* 清理map存储和数据存储
*/
public void clear() {
map.clear();
datas.clear();
} public void addData(Object t){
datas.add(t);
} public void addDatas(List<? extends Object> list) {
datas.addAll(list);
} public List<Object> getDatas() {
return datas;
} }

其中用到了CommonUtils公共类中封装的几个静态方法:

下面开始写测试,编辑一个excel模板:

编写一个测试数据实体(实际使用Map效率会更好一些):

编写测试类,注意模型test.xlsx 已经放入src/model/ 目录下:

输出文件如下:

模板中单元格的样式会延续复制,包含颜色,宽度等等。有兴趣大家可以一起扩展一下。

作者封装了ExcelUtil.createFile()方法。在项目中可以灵活调用。如下代码:

    public boolean exportUersStatistics( String email,Integer userId) throws CetcBigDataException {

        List<UmUserGatherPojo> list=this.findPojo(userId) ;
SheetData sd = new SheetData("用户统计表" ); for (UmUserGatherPojo vo : list) {
sd.addData(vo);
} File file=TemplateExcelUtil.createFile("template_user.xlsx",userId+"user.xlsx",sd); boolean sendResult = mailUtil.sendMail(email, file.getPath(), "用户统计表(月报)", "每月统计注册用户和活跃用户");
if (sendResult) {
return true;
} else {
throw new CetcBigDataException("发送邮件失败");
} }

参考 https://www.iteye.com/blog/jjxliu306-2383610

关于Java中excel表格导出的总结(Java程序导出模板和Java根据模板导出表格两种实现方式)的更多相关文章

  1. java 读取文件——按照行取出(使用BufferedReader和一次将数据保存到内存两种实现方式)

    1.实现目标 读取文件,将文件中的数据一行行的取出. 2.代码实现 1).方式1: 通过BufferedReader的readLine()方法. /** * 功能:Java读取txt文件的内容 步骤: ...

  2. 细说java中Map的两种迭代方式

    曾经对java中迭代方式总是迷迷糊糊的,今天总算弄懂了.特意的总结了一下.基本是算是理解透彻了. 1.再说Map之前先说下Iterator: Iterator主要用于遍历(即迭代訪问)Collecti ...

  3. Java中excel转换为jpg/png图片 采用aspose-cells-18.6.jar

    一  Java中excel转换为jpg/png图片 package com.thinkgem.jeesite.modules.task.util; import com.aspose.cells.Im ...

  4. Java中String对象两种赋值方式的区别

    本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...

  5. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  6. Java中匿名类的两种实现方式(转)

    使用匿名内部类课使代码更加简洁.紧凑,模块化程度更高.内部类能够访问外部内的一切成员变量和方法,包括私有的,而实现接口或继承类做不到.然而这个不是我说的重点,我说的很简单,就是匿名内部类的两种实现方式 ...

  7. Java使用SFTP和FTP两种连接方式实现对服务器的上传下载 【我改】

    []如何区分是需要使用SFTP还是FTP? []我觉得: 1.看是否已知私钥. SFTP 和 FTP 最主要的区别就是 SFTP 有私钥,也就是在创建连接对象时,SFTP 除了用户名和密码外还需要知道 ...

  8. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

  9. Android中Fragment与Activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...

  10. 两种include方式及filter中的dispatcher解析

    两种include方式 我自己写了一个original.jsp,另外有一个includedPage.jsp,我想在original.jsp中把includedPage.jsp引进来有两种方式: 1.& ...

随机推荐

  1. 网络摘抄-深入浅出JVM调优

    基本概念: JVM把内存区分为堆区(heap).栈区(stack)和方法区(method).由于本文主要讲解JVM调优,因此我们可以简单的理解为,JVM中的堆区中存放的是实际的对象,是需要被GC的.其 ...

  2. BFC的理解

    一.BFC概念 BFC即Block Formatting Contexts(块级格式化上下文),它属于普通流.它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其他子元素将如何定位,以及和其他元素 ...

  3. 【Python之路】特别篇--Python装饰器

    前情提要 1. 作用域 在python中,函数会创建一个新的作用域.python开发者可能会说函数有自己的命名空间,差不多一个意思.这意味着在函数内部碰到一个变量的时候函数会优先在自己的命名空间里面去 ...

  4. php有哪些cms框架

    内容管理系统或CMS是一个用于管理新闻的应用程序,用户可以从后台管理系统发布.编辑和删除文章.HTML 和其他脚本语言不需要操作CMS,尽管使用它们会增加更多优势.无疑php的cms框架是最多的,国内 ...

  5. js的三种异步处理

    js的三种异步处理   Promise 对象 含义: Promise是异步编程的一种解决方案, 优点: 相比传统回调函数和事件更加合理和优雅,Promise是链式编程(后面会详细讲述),有效的解决了令 ...

  6. js实现网页上图片循环播放

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/T ...

  7. Catch That Cow (POJ - 3278)(简单BFS)

    转载请注明出处:https://blog.csdn.net/Mercury_Lc/article/details/82693928作者:Mercury_Lc 题目链接 题解:给你x.y,x可以加1.减 ...

  8. Java 注解方式校验请求参数

    1. 参数校验常用注解          注解 验证的数据类型 备注                              Null   任意类型  参数值必须是 Null  NotNull   ...

  9. onReachBottom 注意事项

    onReachBottom使用注意 可在pages.json里定义具体页面底部的触发距离onReachBottomDistance,比如设为50,那么滚动页面到距离底部50px时,就会触发onReac ...

  10. TCP输入 之 tcp_prequeue

    在未开启tcp_low_latency的情况下,软中断将skb送上来,加入到prequeue中,然后 在未启用tcp_low_latency且有用户进程在读取数据的情况下,skb入队到prequeue ...