下面介绍一下JAVA如何读写Excel和word
不用记代码,了解JAVA操作的原理即可,网络上有更好的已经封装好的插件实现导出
写excel时用的是SXSSFWorkbook类+Sheet+Row+Cell+FileOutputStream+File
读excel时用的是
整体代码过于底层,贼麻烦,得手动定义要转为Excel的信息所属实体类,还要手动写set和get,实际开发不用这样写
①首先把下面的代码复制到项目中
②然后替换数组元素的类型,一般是替换为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(); } } } }
大概看一下就行了,知道整个逻辑就是循环套循环,里面的一些方法都过时了,实际开发都用插件,不写这么底层的代码
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(); } }
有这么一个word模板,我们需要根据数据库或者前端给的数据,自动填充到word模板的指定位置上,这就是java写word的一种应用场景
下面给出一个类,了解java如何写word即可,实际开发有更好的插件,不用这种类
将上面的word另存为xml格式的文件,注意,${name1}这种写法就是给java用来识别位置的
①修改文件导出路径、文件名
②给出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(); } } }