POI实现Excel导入导出
作者:互联网
POI实现Excel导入导出
利用idea创建java web的maven项目,在pom中添加对poi的jar的依赖。
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.hand</groupId> 5 <artifactId>excel-data</artifactId> 6 <packaging>war</packaging> 7 <version>1.0-SNAPSHOT</version> 8 <name>excel-data Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 <dependencies> 11 <dependency> 12 <groupId>junit</groupId> 13 <artifactId>junit</artifactId> 14 <version>3.8.1</version> 15 <scope>test</scope> 16 </dependency> 17 <dependency> 18 <groupId>org.apache.poi</groupId> 19 <artifactId>poi</artifactId> 20 <version>3.14</version> 21 </dependency> 22 </dependencies> 23 <build> 24 <finalName>excel-data</finalName> 25 </build> 26 </project>
web.xml中配置下后续导出时,所需要的servlet映射信息:
1 <!DOCTYPE web-app PUBLIC 2 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 3 "http://java.sun.com/dtd/web-app_2_3.dtd" > 4 5 <web-app> 6 <display-name>Archetype Created Web Application</display-name> 7 <servlet> 8 <servlet-name>TestServlet</servlet-name> 9 <servlet-class>TestServlet</servlet-class> 10 </servlet> 11 12 <servlet-mapping> 13 <servlet-name>TestServlet</servlet-name> 14 <url-pattern>/TestServlet</url-pattern> 15 </servlet-mapping> 16 </web-app>
Excel导入工具类实现:
1 import org.apache.poi.hssf.usermodel.*; 2 import org.apache.poi.poifs.filesystem.POIFSFileSystem; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.text.SimpleDateFormat; 8 import java.util.Date; 9 import java.util.HashMap; 10 import java.util.Map; 11 12 /** 13 * @author jiaqing.xu@hand-china.com 14 * @version 1.0 15 * @name 16 * @description 读取并解析excel 17 * @date 2017/10/19 18 */ 19 public class ImportExcel { 20 21 private POIFSFileSystem fs; 22 private HSSFWorkbook wb; 23 private HSSFSheet sheet; 24 private HSSFRow row; 25 26 /** 27 * 读取Excel表格表头的内容 28 * @param is 29 * @return String 表头内容的数组 30 */ 31 public String[] readExcelTitle(InputStream is) { 32 try { 33 fs = new POIFSFileSystem(is); 34 wb = new HSSFWorkbook(fs); 35 } catch (IOException e) { 36 e.printStackTrace(); 37 } 38 sheet = wb.getSheetAt(0); 39 //得到首行的row 40 row = sheet.getRow(0); 41 // 标题总列数 42 int colNum = row.getPhysicalNumberOfCells(); 43 String[] title = new String[colNum]; 44 for (int i = 0; i < colNum; i++) { 45 title[i] = getCellFormatValue(row.getCell((short) i)); 46 } 47 return title; 48 } 49 50 /** 51 * 读取Excel数据内容 52 * @param is 53 * @return Map 包含单元格数据内容的Map对象 54 */ 55 public Map<Integer, String> readExcelContent(InputStream is) { 56 Map<Integer, String> content = new HashMap<Integer, String>(); 57 String str = ""; 58 try { 59 fs = new POIFSFileSystem(is); 60 wb = new HSSFWorkbook(fs); 61 } catch (IOException e) { 62 e.printStackTrace(); 63 } 64 sheet = wb.getSheetAt(0); 65 // 得到总行数 66 int rowNum = sheet.getLastRowNum(); 67 //由于第0行和第一行已经合并了 在这里索引从2开始 68 row = sheet.getRow(2); 69 int colNum = row.getPhysicalNumberOfCells(); 70 // 正文内容应该从第二行开始,第一行为表头的标题 71 for (int i = 2; i <= rowNum; i++) { 72 row = sheet.getRow(i); 73 int j = 0; 74 while (j < colNum) { 75 str += getCellFormatValue(row.getCell((short) j)).trim() + "-"; 76 j++; 77 } 78 content.put(i, str); 79 str = ""; 80 } 81 return content; 82 } 83 84 /** 85 * 获取单元格数据内容为字符串类型的数据 86 * 87 * @param cell Excel单元格 88 * @return String 单元格数据内容 89 */ 90 private String getStringCellValue(HSSFCell cell) { 91 String strCell = ""; 92 switch (cell.getCellType()) { 93 case HSSFCell.CELL_TYPE_STRING: 94 strCell = cell.getStringCellValue(); 95 break; 96 case HSSFCell.CELL_TYPE_NUMERIC: 97 strCell = String.valueOf(cell.getNumericCellValue()); 98 break; 99 case HSSFCell.CELL_TYPE_BOOLEAN: 100 strCell = String.valueOf(cell.getBooleanCellValue()); 101 break; 102 case HSSFCell.CELL_TYPE_BLANK: 103 strCell = ""; 104 break; 105 default: 106 strCell = ""; 107 break; 108 } 109 if (strCell.equals("") || strCell == null) { 110 return ""; 111 } 112 if (cell == null) { 113 return ""; 114 } 115 return strCell; 116 } 117 118 /** 119 * 获取单元格数据内容为日期类型的数据 120 * 121 * @param cell 122 * Excel单元格 123 * @return String 单元格数据内容 124 */ 125 private String getDateCellValue(HSSFCell cell) { 126 String result = ""; 127 try { 128 int cellType = cell.getCellType(); 129 if (cellType == HSSFCell.CELL_TYPE_NUMERIC) { 130 Date date = cell.getDateCellValue(); 131 result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1) 132 + "-" + date.getDate(); 133 } else if (cellType == HSSFCell.CELL_TYPE_STRING) { 134 String date = getStringCellValue(cell); 135 result = date.replaceAll("[年月]", "-").replace("日", "").trim(); 136 } else if (cellType == HSSFCell.CELL_TYPE_BLANK) { 137 result = ""; 138 } 139 } catch (Exception e) { 140 System.out.println("日期格式不正确!"); 141 e.printStackTrace(); 142 } 143 return result; 144 } 145 146 /** 147 * 根据HSSFCell类型设置数据 148 * @param cell 149 * @return 150 */ 151 private String getCellFormatValue(HSSFCell cell) { 152 String cellvalue = ""; 153 if (cell != null) { 154 // 判断当前Cell的Type 155 switch (cell.getCellType()) { 156 // 如果当前Cell的Type为NUMERIC 157 case HSSFCell.CELL_TYPE_NUMERIC: 158 case HSSFCell.CELL_TYPE_FORMULA: { 159 // 判断当前的cell是否为Date 160 if (HSSFDateUtil.isCellDateFormatted(cell)) { 161 Date date = cell.getDateCellValue(); 162 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 163 cellvalue = sdf.format(date); 164 } 165 // 如果是纯数字 166 else { 167 // 取得当前Cell的数值 168 cellvalue = String.valueOf(cell.getNumericCellValue()); 169 } 170 break; 171 } 172 // 如果当前Cell的Type为STRIN 173 case HSSFCell.CELL_TYPE_STRING: 174 // 取得当前的Cell字符串 175 cellvalue = cell.getRichStringCellValue().getString(); 176 break; 177 // 默认的Cell值 178 default: 179 cellvalue = " "; 180 } 181 } else { 182 cellvalue = ""; 183 } 184 return cellvalue; 185 186 } 187 188 public static void main(String[] args) { 189 try { 190 // 对读取Excel表格标题测试 191 InputStream is = new FileInputStream("d:\\test2.xls"); 192 ImportExcel excelReader = new ImportExcel(); 193 String[] title = excelReader.readExcelTitle(is); 194 System.out.println("获得Excel表格的标题:"); 195 for (String s : title) { 196 System.out.print(s + " "); 197 } 198 System.out.println(); 199 200 // 对读取Excel表格内容测试 201 InputStream is2 = new FileInputStream("d:\\test2.xls"); 202 Map<Integer, String> map = excelReader.readExcelContent(is2); 203 System.out.println("获得Excel表格的内容:"); 204 //这里由于xls合并了单元格需要对索引特殊处理 205 for (int i = 2; i <= map.size()+1; i++) { 206 System.out.println(map.get(i)); 207 } 208 209 } catch (FileNotFoundException e) { 210 System.out.println("未找到指定路径的文件!"); 211 e.printStackTrace(); 212 } 213 } 214 215 }
将Excel中的数据通过后台程序维护到一个Map集合中,再利用String的split方法以“-”进行分割,得到单个的值,如果想要将这批数据插入到数据库,则去实例化对象的dto,再给dto对应属性赋值,最终写sql再insert到表中。
Excel导出工具类的实现:
1 import org.apache.poi.hssf.usermodel.*; 2 import org.apache.poi.hssf.util.HSSFColor; 3 import org.apache.poi.ss.usermodel.IndexedColors; 4 import org.apache.poi.ss.util.CellRangeAddress; 5 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 import java.io.IOException; 9 import java.io.OutputStream; 10 import java.util.ArrayList; 11 import java.util.List; 12 13 /** 14 * @author jiaqing.xu@hand-china.com 15 * @version 1.0 16 * @name 17 * @description 18 * @date 2017/10/19 19 */ 20 public class ExportExcel { 21 22 /** 23 * 显示的导出表的标题 24 */ 25 private String title; 26 27 /** 28 * 导出表的列名 29 */ 30 private String[] columnName; 31 32 /** 33 * 需要导出的数据集合 34 */ 35 private List<Object[]> dataList = new ArrayList<Object[]>(); 36 37 /** 38 * 输入流对象 39 */ 40 private HttpServletRequest request; 41 42 /** 43 * 输出流对象 44 */ 45 private HttpServletResponse response; 46 47 48 /** 49 * 50 * @param title 51 * @param columnName 52 * @param dataList 53 * @param request 54 * @param response 55 * @description 构造方法,传入要导出的数据 56 */ 57 public ExportExcel(String title, String[] columnName, List<Object[]> dataList,HttpServletRequest request,HttpServletResponse response) { 58 this.dataList = dataList; 59 this.columnName = columnName; 60 this.title = title; 61 this.request = request; 62 this.response= response; 63 } 64 65 66 /** 67 * @param 68 * @return 69 * @author jiaqing.xu@hand-china.com 70 * @date 2017/10/19 13:21 71 * @description 导出数据到excel 72 */ 73 public void export() throws Exception { 74 75 try { 76 HSSFWorkbook workbook = new HSSFWorkbook(); // 创建工作簿对象 77 HSSFSheet sheet = workbook.createSheet(title); // 创建工作表 78 79 // 产生表格标题行 80 HSSFRow rowm = sheet.createRow(0); 81 HSSFCell cellTiltle = rowm.createCell(0); 82 83 //设置标题和单元格样式 84 HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook); //获取列头样式对象 85 HSSFCellStyle style = this.getStyle(workbook); //单元格样式对象 86 87 //合并单元格 88 sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (columnName.length - 1))); 89 cellTiltle.setCellStyle(columnTopStyle); 90 cellTiltle.setCellValue(title); 91 92 // 定义所需列数 93 int columnNum = columnName.length; 94 HSSFRow rowRowName = sheet.createRow(2); // 在索引2的位置创建行(最顶端的行开始的第二行) 95 96 97 // 将列头设置到sheet的单元格中 98 for (int n = 0; n < columnNum; n++) { 99 HSSFCell cellRowName = rowRowName.createCell(n); //创建列头对应个数的单元格 100 cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING); //设置列头单元格的数据类型 101 HSSFRichTextString text = new HSSFRichTextString(columnName[n]); 102 cellRowName.setCellValue(text); //设置列头单元格的值 103 cellRowName.setCellStyle(columnTopStyle); //设置列头单元格样式 104 } 105 106 //将查询出的数据设置到sheet对应的单元格中 107 for (int i = 0; i < dataList.size(); i++) { 108 Object[] obj = dataList.get(i);//遍历每个对象 109 HSSFRow row = sheet.createRow(i + 3);//创建所需的行数 110 for (int j = 0; j < obj.length; j++) { 111 HSSFCell cell = null; //设置单元格的数据类型 112 //第一列为数字类型并设置单元格的值 113 if (j == 0) { 114 cell = row.createCell(j, HSSFCell.CELL_TYPE_NUMERIC); 115 cell.setCellValue(i + 1); 116 } else { 117 //其他列为字符串类型并设置单元格的值 118 cell = row.createCell(j, HSSFCell.CELL_TYPE_STRING); 119 if (!"".equals(obj[j]) && obj[j] != null) { 120 cell.setCellValue(obj[j].toString()); 121 } 122 } 123 cell.setCellStyle(style); //设置单元格样式 124 } 125 } 126 127 128 //让列宽随着导出的列长自动适应 129 for (int colNum = 0; colNum < columnNum; colNum++) { 130 int columnWidth = sheet.getColumnWidth(colNum) / 256; 131 for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) { 132 HSSFRow currentRow; 133 //当前行未被使用过 134 if (sheet.getRow(rowNum) == null) { 135 currentRow = sheet.createRow(rowNum); 136 } else { 137 currentRow = sheet.getRow(rowNum); 138 } 139 if (currentRow.getCell(colNum) != null) { 140 //取得当前的单元格 141 HSSFCell currentCell = currentRow.getCell(colNum); 142 //如果当前单元格类型为字符串 143 if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) { 144 int length = currentCell.getStringCellValue().getBytes().length; 145 if (columnWidth < length) { 146 //将单元格里面值大小作为列宽度 147 columnWidth = length; 148 } 149 } 150 } 151 } 152 //再根据不同列单独做下处理 153 if (colNum == 0) { 154 sheet.setColumnWidth(colNum, (columnWidth - 2) * 256); 155 } else { 156 sheet.setColumnWidth(colNum, (columnWidth + 4) * 256); 157 } 158 } 159 160 if (workbook != null) { 161 try { 162 String fileName = "Excel-" + String.valueOf(System.currentTimeMillis()).substring(4, 13) + ".xls"; 163 String headStr = "attachment; filename=\"" + fileName + "\""; 164 response.setContentType("APPLICATION/OCTET-STREAM"); 165 response.setHeader("Content-Disposition", headStr); 166 OutputStream out1 = response.getOutputStream(); 167 workbook.write(out1); 168 } catch (IOException e) { 169 e.printStackTrace(); 170 } 171 } 172 173 } catch (Exception e) { 174 e.printStackTrace(); 175 } 176 } 177 178 179 /** 180 * @param 181 * @return 182 * @author jiaqing.xu@hand-china.com 183 * @date 2017/10/19 13:31 184 * @description 标题行的单元格样式 185 */ 186 public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) { 187 188 // 设置字体 189 HSSFFont font = workbook.createFont(); 190 //设置字体大小 191 font.setFontHeightInPoints((short) 11); 192 //字体加粗 193 font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); 194 //设置字体名字 195 font.setFontName("Courier New"); 196 //设置样式; 197 HSSFCellStyle style = workbook.createCellStyle(); 198 style.setFillForegroundColor(IndexedColors.BLUE.getIndex()); 199 //设置底边框; 200 style.setBorderBottom(HSSFCellStyle.BORDER_THIN); 201 //设置底边框颜色; 202 style.setBottomBorderColor(HSSFColor.BLACK.index); 203 //设置左边框; 204 style.setBorderLeft(HSSFCellStyle.BORDER_THIN); 205 //设置左边框颜色; 206 style.setLeftBorderColor(HSSFColor.BLACK.index); 207 //设置右边框; 208 style.setBorderRight(HSSFCellStyle.BORDER_THIN); 209 //设置右边框颜色; 210 style.setRightBorderColor(HSSFColor.BLACK.index); 211 //设置顶边框; 212 style.setBorderTop(HSSFCellStyle.BORDER_THIN); 213 //设置顶边框颜色; 214 style.setTopBorderColor(HSSFColor.BLACK.index); 215 //在样式用应用设置的字体; 216 style.setFont(font); 217 //设置自动换行; 218 style.setWrapText(false); 219 //设置水平对齐的样式为居中对齐; 220 style.setAlignment(HSSFCellStyle.ALIGN_CENTER); 221 //设置垂直对齐的样式为居中对齐; 222 style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); 223 return style; 224 } 225 226 /** 227 * @param 228 * @return 229 * @author jiaqing.xu@hand-china.com 230 * @date 2017/10/19 13:31 231 * @description 列数据信息单元格样式 232 */ 233 public HSSFCellStyle getStyle(HSSFWorkbook workbook) { 234 // 设置字体 235 HSSFFont font = workbook.createFont(); 236 //设置字体大小 237 //font.setFontHeightInPoints((short)10); 238 //字体加粗 239 //font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); 240 //设置字体名字 241 font.setFontName("Courier New"); 242 //设置样式; 243 HSSFCellStyle style = workbook.createCellStyle(); 244 //设置底边框; 245 style.setBorderBottom(HSSFCellStyle.BORDER_THIN); 246 //设置底边框颜色; 247 style.setBottomBorderColor(HSSFColor.BLACK.index); 248 //设置左边框; 249 style.setBorderLeft(HSSFCellStyle.BORDER_THIN); 250 //设置左边框颜色; 251 style.setLeftBorderColor(HSSFColor.BLACK.index); 252 //设置右边框; 253 style.setBorderRight(HSSFCellStyle.BORDER_THIN); 254 //设置右边框颜色; 255 style.setRightBorderColor(HSSFColor.BLACK.index); 256 //设置顶边框; 257 style.setBorderTop(HSSFCellStyle.BORDER_THIN); 258 //设置顶边框颜色; 259 style.setTopBorderColor(HSSFColor.BLACK.index); 260 //在样式用应用设置的字体; 261 style.setFont(font); 262 //设置自动换行; 263 style.setWrapText(false); 264 //设置水平对齐的样式为居中对齐; 265 style.setAlignment(HSSFCellStyle.ALIGN_CENTER); 266 //设置垂直对齐的样式为居中对齐; 267 style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); 268 return style; 269 } 270 }
用于测试导出的Servlet程序:
1 import javax.servlet.ServletException; 2 import javax.servlet.annotation.WebServlet; 3 import javax.servlet.http.HttpServlet; 4 import javax.servlet.http.HttpServletRequest; 5 import javax.servlet.http.HttpServletResponse; 6 import java.io.IOException; 7 import java.util.ArrayList; 8 import java.util.List; 9 10 /** 11 * @author jiaqing.xu@hand-china.com 12 * @version 1.0 13 * @name 14 * @description 15 * @date 2017/10/19 16 */ 17 @WebServlet(name = "TestServlet") 18 public class TestServlet extends HttpServlet { 19 @Override 20 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 21 String title = "货运单据导出"; 22 String[] columnName = new String[]{"序号","num1","num2"}; 23 List<Object[]> dataList = new ArrayList<Object[]>(); 24 Object[] objs; 25 for (int i = 0; i <2; i++) { 26 objs = new Object[columnName.length]; 27 objs[0] = i; 28 objs[1] = "1"; 29 objs[2] = "2"; 30 dataList.add(objs); 31 } 32 //实例化工具类 33 ExportExcel ex = new ExportExcel(title, columnName, dataList,request,response); 34 try { 35 //导出excel 36 ex.export(); 37 } catch (Exception e) { 38 e.printStackTrace(); 39 } 40 } 41 42 @Override 43 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 44 doPost(request,response); 45 } 46 }
标签:style,sheet,HSSFCellStyle,单元格,Excel,导入,设置,POI,import 来源: https://blog.csdn.net/weixin_43949758/article/details/89278044