022医疗项目-模块二:药品目录的导入导出-对XSSF导出excel类进行封装
Posted jim_shen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了022医疗项目-模块二:药品目录的导入导出-对XSSF导出excel类进行封装相关的知识,希望对你有一定的参考价值。
资源全部来源于传智播客。
好的架构师写的程序,就算给刚入门的新手看,新手一看就知道怎么去用。所以我们要对XSSF导出excel类进行封装。这是架构师的工作,但我们也要知道。
我们写一个封装类:
这个类单独有自己的main函数。
我们进入main函数一步一步看:
public static void main(String[] args) throws Exception { /** 导出文件存放物理路径 * @param fileWebPath * 导出文件web下载路径 * @param filePrefix * 导出文件名的前缀 * @param flushRows * 存放在内存的数据量 * @param fieldNames * 导出文件列标题 * @param fieldCodes * 导出数据对象的字段名称 * @param flushRows*/ //导出文件存放的路径,并且是虚拟目录指向的路径 String filePath = "d:/upload/linshi/"; //导出文件的前缀 String filePrefix="ypxx"; //-1表示关闭自动刷新,手动控制写磁盘的时机,其它数据表示多少数据在内存保存,超过的则写入磁盘 int flushRows=100; //指导导出数据的title List<String> fieldNames=new ArrayList<String>(); fieldNames.add("流水号"); fieldNames.add("通用名"); fieldNames.add("价格"); //告诉导出类数据list中对象的属性,让ExcelExportSXXSSF通过反射获取对象的值 List<String> fieldCodes=new ArrayList<String>(); fieldCodes.add("bm");//药品流水号 fieldCodes.add("mc");//通用名 fieldCodes.add("price");//价格 //注意:fieldCodes和fieldNames个数必须相同且属性和title顺序一一对应,这样title和内容才一一对应 //开始导出,执行一些workbook及sheet等对象的初始创建 ExcelExportSXXSSF excelExportSXXSSF = ExcelExportSXXSSF.start(filePath, "/upload/", filePrefix, fieldNames, fieldCodes, flushRows); //准备导出的数据,将数据存入list,且list中对象的字段名称必须是刚才传入ExcelExportSXXSSF的名称 List<Ypxx> list = new ArrayList<Ypxx>(); Ypxx ypxx1 = new Ypxx("001", "青霉素", 5); Ypxx ypxx2 = new Ypxx("002", "感冒胶囊", 2.5f); list.add(ypxx1); list.add(ypxx2); //执行导出 excelExportSXXSSF.writeDatasByObject(list); //输出文件,返回下载文件的http地址 String webpath = excelExportSXXSSF.exportFile(); System.out.println(webpath); }
首先,我们看fieldNames和fieldCodes这两个List。fielNames里面存放的是Excel文件的标题,我们设置为“流水号”“通用名”“价格”。而filedCodes存放的是标题对应的数据,这个数据来自于查出来的数据库。
比如说,我们从数据库中查出来一个pojo类是Ypxx.
Ypxx里面有bm,mc,price三个属性。那么我们这个bm的值就要设置在l“流水号”中,mc就要设置在"通用名”中,price就要设置在“价格”中。
最后形成的效果就是:
好,我们接下来看看具体是怎么实现的:
ExcelExportSXXSSF excelExportSXXSSF = ExcelExportSXXSSF.start(filePath, "/upload/", filePrefix, fieldNames, fieldCodes, flushRows);
我们具体看一下start函数里面都做了什么.
public static ExcelExportSXXSSF start(String filePath, String fileWebPath,String filePrefix, List<String> fieldNames,List<String> fieldCodes, int flushRows) throws Exception { ExcelExportSXXSSF excelExportSXXSSF = new ExcelExportSXXSSF(); excelExportSXXSSF.setFilePath(filePath); excelExportSXXSSF.setFileWebPath(fileWebPath); excelExportSXXSSF.setFilePrefix(filePrefix); excelExportSXXSSF.setFieldNames(fieldNames); excelExportSXXSSF.setFieldCodes(fieldCodes); excelExportSXXSSF.setWb(new SXSSFWorkbook(flushRows));//创建workbook excelExportSXXSSF.setSh(excelExportSXXSSF.getWb().createSheet());//创建sheet excelExportSXXSSF.writeTitles(); return excelExportSXXSSF; }
start里面的writeTitles函数我们来看一下:
/** * 设置导入文件的标题 * 开始生成导出excel的标题 * @throws Exception */ private void writeTitles() throws Exception { rownum = 0;//第0行 colnum = fieldNames.size();//根据列标题得出列数 Row row = sh.createRow(rownum); for (int cellnum = 0; cellnum < colnum; cellnum++) { Cell cell = row.createCell(cellnum); cell.setCellValue(fieldNames.get(cellnum)); } }
这个函数的功能是:就是Excel表的标题写好。
就是“流水号”,“通用名”,“价格”。
执行完start之后就去执行
List<Ypxx> list = new ArrayList<Ypxx>(); Ypxx ypxx1 = new Ypxx("001", "青霉素", 5); Ypxx ypxx2 = new Ypxx("002", "感冒胶囊", 2.5f); list.add(ypxx1); list.add(ypxx2);
这些代码就是模仿从数据库中取出数据,填入到excel表格中。
最后执行的是
excelExportSXXSSF.writeDatasByObject(list);这一行是关键所在:
给出具体的实现:
/** * 向导出文件写数据 * * @param datalist * 存放Object对象,仅支持单个自定义对象,不支持对象中嵌套自定义对象 * @return */ public void writeDatasByObject(List datalist) throws Exception { for (int j = 0; j < datalist.size(); j++) { rownum = rownum + 1; Row row = sh.createRow(rownum); for (int cellnum = 0; cellnum < fieldCodes.size(); cellnum++) { Object owner = datalist.get(j); Object value = invokeMethod(owner, fieldCodes.get(cellnum), new Object[] {}); Cell cell = row.createCell(cellnum); cell.setCellValue(value!=null?value.toString():""); } } }
第一个for循环就是遍历每一个pojo数据(一个就是一行),第二个for循环就是得到每一个pojo类里面的属性值。这里用的是反射。nvokeMethod。这里的value就是我们的每一个值。我们看一下 Object value = invokeMethod(owner, fieldCodes.get(cellnum)函数。
/** * 反射方法,通过get方法获取对象属性 * * @param owner * @param fieldname * @param args * @return * @throws Exception */ private Object invokeMethod(Object owner, String fieldname, Object[] args) throws Exception { String methodName = "get" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1); Class ownerClass = owner.getClass(); Class[] argsClass = new Class[args.length]; for (int i = 0, j = args.length; i < j; i++) { argsClass[i] = args[i].getClass(); } Method method = ownerClass.getMethod(methodName, argsClass); return method.invoke(owner, args); }
下面给出整个封装类代码:
整体代码:
package yycg.util; import java.io.FileOutputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; /** * excel导出的封装类 * @author miaoruntu * */ public class ExcelExportSXXSSF { // 定义工作表 private SXSSFWorkbook wb; /** * 定义工作表中的sheet */ private Sheet sh; /** * 定义保存在内存中的数量,-1表示手动控制 */ private int flushRows; /** 导出文件行数 */ private int rownum; /** 导出文件列数 */ private int colnum; /** 导出文件的存放路径 */ private String filePath; /** 下载导出文件的路径 */ private String fileWebPath; /**文件名称前缀*/ private String filePrefix; /**导出文件全路径*/ private String fileAllPath; /** 导出文件列标题 */ private List<String> fieldNames; /**导出文件每列代码,用于反射获取对象属性值*/ private List<String> fieldCodes; private ExcelExportSXXSSF() { } /** * 开始导出方法 * * @param filePath * 导出文件存放物理路径 * @param fileWebPath * 导出文件web下载路径 * @param filePrefix * 导出文件名的前缀 * @param flushRows * 存放在内存的数据量 * @param fieldNames * 导出文件列标题 * @param fieldCodes * 导出数据对象的字段名称 * @param flushRows * 写磁盘控制参数 * @return */ public static ExcelExportSXXSSF start(String filePath, String fileWebPath,String filePrefix, List<String> fieldNames,List<String> fieldCodes, int flushRows) throws Exception { ExcelExportSXXSSF excelExportSXXSSF = new ExcelExportSXXSSF(); excelExportSXXSSF.setFilePath(filePath); excelExportSXXSSF.setFileWebPath(fileWebPath); excelExportSXXSSF.setFilePrefix(filePrefix); excelExportSXXSSF.setFieldNames(fieldNames); excelExportSXXSSF.setFieldCodes(fieldCodes); excelExportSXXSSF.setWb(new SXSSFWorkbook(flushRows));//创建workbook excelExportSXXSSF.setSh(excelExportSXXSSF.getWb().createSheet());//创建sheet excelExportSXXSSF.writeTitles(); return excelExportSXXSSF; } /** * 设置导入文件的标题 * 开始生成导出excel的标题 * @throws Exception */ private void writeTitles() throws Exception { rownum = 0;//第0行 colnum = fieldNames.size();//根据列标题得出列数 Row row = sh.createRow(rownum); for (int cellnum = 0; cellnum < colnum; cellnum++) { Cell cell = row.createCell(cellnum); cell.setCellValue(fieldNames.get(cellnum)); } } /** * 向导出文件写数据 * * @param datalist * 存放Object对象,仅支持单个自定义对象,不支持对象中嵌套自定义对象 * @return */ public void writeDatasByObject(List datalist) throws Exception { for (int j = 0; j < datalist.size(); j++) { rownum = rownum + 1; Row row = sh.createRow(rownum); for (int cellnum = 0; cellnum < fieldCodes.size(); cellnum++) { Object owner = datalist.get(j); Object value = invokeMethod(owner, fieldCodes.get(cellnum), new Object[] {}); Cell cell = row.createCell(cellnum); cell.setCellValue(value!=null?value.toString():""); } } } /** * 向导出文件写数据 * * @param datalist * 存放字符串数组 * @return */ public void writeDatasByString(List<String> datalist) throws Exception { rownum = rownum + 1; Row row = sh.createRow(rownum); int datalist_size = datalist.size(); for (int cellnum = 0; cellnum < colnum; cellnum++) { Cell cell = row.createCell(cellnum); if(datalist_size>cellnum){ cell.setCellValue(datalist.get(cellnum)); }else{ cell.setCellValue(""); } } } /** * 手动刷新方法,如果flushRows为-1则需要使用此方法手动刷新内存 * * @param flushRows * @throws Exception */ public void flush(int flushNum) throws Exception { ((SXSSFSheet) sh).flushRows(flushNum); } /** * 导出文件 * * @throws Exception */ public String exportFile() throws Exception { String filename = filePrefix+"_"+MyUtil.getCurrentTimeStr() + ".xlsx"; FileOutputStream out = new FileOutputStream(filePath + filename); wb.write(out); out.flush(); out.close(); setFileAllPath(fileWebPath + filename); return fileWebPath + filename; } /** * 反射方法,通过get方法获取对象属性 * * @param owner * @param fieldname * @param args * @return * @throws Exception */ private Object invokeMethod(Object owner, String fieldname, Object[] args) throws Exception { String methodName = "get" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1); Class ownerClass = owner.getClass(); Class[] argsClass = new Class[args.length]; for (int i = 0, j = args.length; i < j; i++) { argsClass[i] = args[i].getClass(); } Method method = ownerClass.getMethod(methodName, argsClass); return method.invoke(owner, args); } public SXSSFWorkbook getWb() { return wb; } public void setWb(SXSSFWorkbook wb) { this.wb = wb; } public Sheet getSh() { return sh; } public void setSh(Sheet sh) { this.sh = sh; } public int getFlushRows() { return flushRows; } public void setFlushRows(int flushRows) { this.flushRows = flushRows; } public String getFilePath() { return filePath; } public void setFilePath(String filePath) { this.filePath = filePath; } public String getFileWebPath() { return fileWebPath; } public void setFileWebPath(String fileWebPath) { this.fileWebPath = fileWebPath; } public List<String> getFieldNames() { return fieldNames; } public void setFieldNames(List<String> fieldNames) { this.fieldNames = fieldNames; } public List<String> getFieldCodes() { return fieldCodes; } public void setFieldCodes(List<String> fieldCodes) { this.fieldCodes = fieldCodes; } public int getRownum() { return rownum; } public String getFilePrefix() { return filePrefix; } public void setFilePrefix(String filePrefix) { this.filePrefix = filePrefix; } public int getColnum() { return colnum; } public String getFileAllPath() { return fileAllPath; } public void setFileAllPath(String fileAllPath) { this.fileAllPath = fileAllPath; } public static void main(String[] args) throws Exception { /** 导出文件存放物理路径 * @param fileWebPath * 导出文件web下载路径 * @param filePrefix * 导出文件名的前缀 * @param flushRows * 存放在内存的数据量 * @param fieldNames * 导出文件列标题 * @param fieldCodes * 导出数据对象的字段名称 * @param flushRows*/ //导出文件存放的路径,并且是虚拟目录指向的路径 String filePath = "d:/upload/linshi/"; //导出文件的前缀 String filePrefix="ypxx"; //-1表示关闭自动刷新,手动控制写磁盘的时机,其它数据表示多少数据在内存保存,超过的则写入磁盘 int flushRows=100; //指导导出数据的title List<String> fieldNames=new ArrayList<String>(); fieldNames.add("流水号"); fieldNames.add("通用名"); fieldNames.add("价格"); //告诉导出类数据list中对象的属性,让ExcelExportSXXSSF通过反射获取对象的值 List<String> fieldCodes=new ArrayList<String>(); fieldCodes.add("bm");//药品流水号 fieldCodes.add("mc");//通用名 fieldCodes.add("price");//价格 //注意:fieldCodes和fieldNames个数必须相同且属性和title顺序一一对应,这样title和内容才一一对应 //开始导出,执行一些workbook及sheet等对象的初始创建 ExcelExportSXXSSF excelExportSXXSSF = ExcelExportSXXSSF.start(filePath, "/upload/", filePrefix, fieldNames, fieldCodes, flushRows); //准备导出的数据,将数据存入list,且list中对象的字段名称必须是刚才传入ExcelExportSXXSSF的名称 List<Ypxx> list = new ArrayList<Ypxx>(); Ypxx ypxx1 = new Ypxx("001", "青霉素", 5); Ypxx ypxx2 = new Ypxx("002", "感冒胶囊", 2.5f); list.add(ypxx1); list.add(ypxx2); //执行导出 excelExportSXXSSF.writeDatasByObject(list); //输出文件,返回下载文件的http地址 String webpath = excelExportSXXSSF.exportFile(); System.out.println(webpath); } }
以上是关于022医疗项目-模块二:药品目录的导入导出-对XSSF导出excel类进行封装的主要内容,如果未能解决你的问题,请参考以下文章
026医疗项目-模块二:药品目录的导入导出-导入功能的Service的编写
025医疗项目-模块二:药品目录的导入导出-HSSF导入类的封装
023医疗项目-模块二:药品目录的导入导出-从数据库中查出数据用XSSF导出excel并存放在虚拟目录最后下载(包括调试)