1 概述
下面介绍一下JAVA如何读写Excel和word
不用记代码,了解JAVA操作的原理即可,网络上有更好的已经封装好的插件实现导出
写excel时用的是SXSSFWorkbook类+Sheet+Row+Cell+FileOutputStream+File
读excel时用的是
整体代码过于底层,贼麻烦,得手动定义要转为Excel的信息所属实体类,还要手动写set和get,实际开发不用这样写
2 写Excel 操作
①首先把下面的代码复制到项目中
②然后替换数组元素的类型,一般是替换为VO类,根据业务需要,也可以储存为PO或者DTO
③接着根据业务需求或者VO类的属性,手动设置标题行的字段
④最后在for循环里手动设置Excel每一列数据与VO类的属性的对应
⑤外部调用这个方法时,把查询到的数组、保存路径、保存文件名传入即可
public class ExcelReaderDemo {
public static void write(List<SalesOrderVO> list, String path,String name){
//声明一个流对象
FileOutputStream fileOutputStream = null;
try {
//创建File类 由外部传入文件在磁盘上的绝对路径+文件名 再手动拼接文件后缀
File file = new File(path+name+".xls");
fileOutputStream = new FileOutputStream(file);
//创建一个SXSSFWorkbook类 设定每100个row自动保存到硬盘
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
//创建Excel文件中的页面 或者说 在工作簿中创建工作表
Sheet sheet = workbook.createSheet("表1");
//1.创建标题行 0对应Excel中的第一行
Row titleRow = sheet.createRow(0);
//2.给标题行的每一列分别设置字段 0对应第一列
Cell cell = titleRow.createCell(0);
cell.setCellValue("订单表主键");
cell = titleRow.createCell(1);
cell.setCellValue("订单编号");
cell = titleRow.createCell(2);
cell.setCellValue("订单分类");
cell = titleRow.createCell(3);
cell.setCellValue("订单动作");
cell = titleRow.createCell(4);
cell.setCellValue("订单状态");
//3.遍历List 获取到单个元素,每个元素映射为一行记录
for (int i = 0; i <list.size() ; i++) {
SalesOrderVO userInfo = list.get(i);
//4.在当前工作表下创建行
//数组的第一个元素为sheet.createRow(1),对应表格中的第二行
titleRow = sheet.createRow(i+1);
//5.创建行后,为当前行的每列放入数据,此数据对应元素的每个属性
cell = titleRow.createCell(0);
cell.setCellValue(userInfo.getOrderId()==null?"":userInfo.getOrderId().toString());
cell = titleRow.createCell(1);
cell.setCellValue(userInfo.getOrderNumber()==null?"":userInfo.getOrderNumber().toString());
cell = titleRow.createCell(2);
cell.setCellValue(userInfo.getOrderClass()==null ? "" : userInfo.getOrderClass().toString());
cell = titleRow.createCell(3);
cell.setCellValue(userInfo.getOrderAction() == null ? "":userInfo.getOrderAction());
cell = titleRow.createCell(4);
cell.setCellValue(userInfo.getOrderStatus() == null ? "":userInfo.getOrderStatus());
//6.Excel的单元格有数据格式的区别 如果数据是时间 那么要手动指定数据格式
// String birth = null;
// if(userInfo.getBirthday() != null){
// birth = DateUtil.format(userInfo.getBirthday(), "yyyy年MM月dd日 HH:mm:ss");
// }
// cell.setCellValue(birth);
// cell = titleRow.createCell(5);
// String updtime = null;
// if(userInfo.getUpd_time() != null){
// updtime = DateUtil.format(userInfo.getUpd_time(), "yyyy年MM月dd日 HH:mm:ss");
// }
// cell.setCellValue(updtime);
// cell = titleRow.createCell(6);
// cell.setCellValue(userInfo.getAddress() == null ? "" : userInfo.getAddress());
}
//7. 调用SXSSFWorkbook类的write方法,将SXSSFWorkbook对象的数据写到流对象指向的磁盘文件中
workbook.write(fileOutputStream);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(fileOutputStream!= null) fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3 读Excel 操作
大概看一下就行了,知道整个逻辑就是循环套循环,里面的一些方法都过时了,实际开发都用插件,不写这么底层的代码
public static void reader(){
try {
//1.声明文件对象,根据路径获取到excel文件信息,读入java代码,转为file对象
File file = new File("C:\\Users\\Administrator\\Desktop\\123_s_user_info.xls");
//2.根据文件对象创建workbook核心对象
Workbook workbook = WorkbookFactory.create(file);
//3.根据workbook核心对象获取 sheet的数量
int numberOfSheets = workbook.getNumberOfSheets();
System.out.println("当前的Sheets的数量 : " + numberOfSheets);
Sheet sheetAt = workbook.getSheetAt(0); //获取第1个工作表
int firstRowNum = sheetAt.getFirstRowNum(); //第一行的索引
int lastRowNum = sheetAt.getLastRowNum(); //最后一行的索引 作为循环的次数依据
//4.声明一个数组 用来储存对象
ArrayList<UserInfo> userInfos = new ArrayList<>();
//5.以最后一行的索引作为循环的次数依据,遍历excel,每行数据对应一个userInfo对象,存放到声明的数组中
for (int j = 1; j <= lastRowNum; j++) {
//6.每次遍历获得一行的数据 存在Row类中
Row row = sheetAt.getRow(j);
//7.创建一个SimpleDateFormat类 用于处理excel表中的时间数据的数据格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//8.声明变量 对一行数据的每一个单元格进行判空 不为空则取出存入声明的变量中
Integer id = null;
if(row.getCell(0) != null){
id = Integer.parseInt(row.getCell(0).getStringCellValue());
}
Double salary = null;
if(row.getCell(1) != null){
salary = Double.parseDouble(row.getCell(1).getStringCellValue());
}
String gender = null;
if(row.getCell(2) != null){
gender = row.getCell(2).getStringCellValue();
}
String name=null;
if(row.getCell(3) != null){
name = row.getCell(3).getStringCellValue();
}
Date birthday = null;
if(row.getCell(4) != null){
birthday = simpleDateFormat.parse(row.getCell(4).getStringCellValue());
}
Date updTime = null;
if(row.getCell(5) != null){
updTime = simpleDateFormat.parse(row.getCell(5).getStringCellValue());
}
String address = null;
if(row.getCell(6) != null){
address = row.getCell(6).getStringCellValue();
}
//9.将获取到的数据传入对象的构造函数 形成对象
UserInfo userInfo = new UserInfo(id, salary, gender, name, birthday, updTime, address);
//10.将对象存入数组
userInfos.add(userInfo);
//dao.addUser(); //单个添加效率极低,禁止使用
if(userInfos.size() == 10000){
//执行批量添加
userInfos.clear();
}
}
System.out.println(userInfos);
} catch (Exception e) {
e.printStackTrace();
}
}
4 写word
有这么一个word模板,我们需要根据数据库或者前端给的数据,自动填充到word模板的指定位置上,这就是java写word的一种应用场景
下面给出一个类,了解java如何写word即可,实际开发有更好的插件,不用这种类
4.1 步骤一 准备xml文件
将上面的word另存为xml格式的文件,注意,${name1}这种写法就是给java用来识别位置的
4.2 步骤二 把代码存到项目中
①修改文件导出路径、文件名
②给出xml文件名、文件所在路径
③给定word模板中那些变量的值,存在map中
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
public class WordDemo {
public void writeWord(){
try {
//定义一个map 向其中存入key-value 其中key与word模板中的变量名要一致
Map<String,Object> map = new HashMap<>();
map.put("name1","王建林");
map.put("name2","凤姐");
map.put("age","12");
map.put("phone","18555555555");
map.put("address","湖北武汉");
//设定即将要导出的word文件存放路径
Writer out = new OutputStreamWriter(new FileOutputStream("E:\\房屋合同.docx"), "UTF-8");
//freemarker.template.Configuration
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");//设置编码
//类加载器,设置xml模板文件的路径
configuration.setClassForTemplateLoading(this.getClass(), "/");
//获取模板对象 传入模板名称
Template t = configuration.getTemplate("房屋合同.xml");
t.process(map, out);//模板中传入数据
out.close();
} catch (IOException | TemplateException e) {
e.printStackTrace();
}
}
}