Poi 读写Excel 合并ExcelSheet Struts2实现

来源:互联网 发布:游戏王软件 编辑:程序博客网 时间:2024/06/06 03:42

网上有许多人在找这样的例子,有多个Excel,要把他们合并到一个Excel里面,这里涉及无非是Excel的读取和Sheet的合并。

我做了这样一个实现,可以参考,当然更希望指点。使用Struts实现他的上传功能,在把多个Excel上传到Action后,进行合并,然后直接执行下载。也就是说,我们一个Action里要动用Struts2的上传和下载两个功能。

实现的步骤:

1.拷贝Struts的包到工程(估计都会吧,Ctrl+C 加 Ctrl + V)

2.在Web.xml里配置Struts2,也不难

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list></web-app>

 

3.定义Struts2的配置文件

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"><struts><!-- 一些基本配置,自己看着办 --><constant name="struts.devMode" value="false"></constant><constant name="struts.i18n.reload" value="true"></constant><constant name="struts.i18n.encoding" value="UTF-8"></constant><constant name="struts.multipart.saveDir" value="C:\\"></constant><constant name="struts.multipart.maxSize" value="20971520"></constant><package name="default" namespace="/" extends="struts-default"><action name="doUpload"class="com.golden.action.StrutsFileUpload"><result name="success" type="stream"><param name="contentType">application/vnd.ms-excel</param><param name="contentDisposition">attachment;filename="TEST.xls"</param><param name="inputName">downLoadStream</param><param name="bufferSize">4096</param></result></action></package></struts>

 

注意:

contentType:要设置为下载类型为Excel,当然这些可以在Actoin里动态定义,想实现的具体再说。

contentDisposition:里面千万不要忘了attachment;不然可能会出一些问题,当然也许有的人不写。后面是下载的文件名,也可以在Action里定义。

inputName:真正执行下载的方法

bufferSize:缓冲区大小

3.写一个上传页面

<%@ page language="java" pageEncoding="UTF-8"%><%@ taglib prefix="s" uri="/struts-tags" %><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>多文件Excel分析</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page">  </head>    <body>    <center>    <s:form action="doUpload" method="POST" enctype="multipart/form-data">            <s:file name="upload" label="上传的文件1" />            <s:file name="upload" label="上传的文件2" />            <s:file name="upload" label="上传的文件3" />            <s:file name="upload" label="上传的文件4" />            <s:file name="upload" label="上传的文件5" />            <s:file name="upload" label="上传的文件6" />            <s:submit value="上   传"/>        </s:form>    </center>  </body></html>

 

注意:

里面使用了Struts2的标签,也可以直接使用Html标签

4.最关键的部分,写Action的类

package com.golden.action;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import org.apache.poi.hssf.usermodel.HSSFCell;import org.apache.poi.hssf.usermodel.HSSFCellStyle;import org.apache.poi.hssf.usermodel.HSSFDateUtil;import org.apache.poi.hssf.usermodel.HSSFRow;import org.apache.poi.hssf.usermodel.HSSFSheet;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import com.opensymphony.xwork2.ActionSupport;import java.math.*;import java.text.NumberFormat;@SuppressWarnings("serial")public class StrutsFileUpload extends ActionSupport {private File[] upload;// 实际上传文件private String[] uploadContentType; // 文件的内容类型private String[] uploadFileName; // 上传文件名/** * 请求的Action */@Overridepublic String execute() throws Exception {return "success";}/** * 真正的下载方法 *  * @return * @throws Exception */@SuppressWarnings("deprecation")public InputStream getDownLoadStream() throws Exception {HSSFWorkbook wb = new HSSFWorkbook();// 设置一个靠右排放样式,如果需要其他样式自可以再定义一些HSSFCellStyle style = wb.createCellStyle();// style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);style.setAlignment(HSSFCellStyle.ALIGN_RIGHT); // 在单元格中右排放try {for (int i = 0; i < upload.length; i++) {File f = upload[i]; // 取得一个文件FileInputStream is = new FileInputStream(f);HSSFWorkbook wbs = new HSSFWorkbook(is);// 根据读出的Excel,创建SheetHSSFSheet sheet = wb.createSheet(uploadFileName[i]);// 一直取的是第一个Sheet,一定要注意,如果你要读取所有的Sheet,循环读取即可HSSFSheet childSheet = wbs.getSheetAt(0);// 循环读取Excel的行for (int j = 0; j < childSheet.getLastRowNum(); j++) {// 根据读取的行,创建要合并Sheet的行HSSFRow r = sheet.createRow(j);HSSFRow row = childSheet.getRow(j);// 判断是否为空,因为可能出现空行的情况if (null != row) {// 循环读取列for (int k = 0; k < row.getLastCellNum(); k++) {// 根据读取的列,创建列HSSFCell c = r.createCell(k);HSSFCell cell = row.getCell(k);// 将值和样式一同赋值给单元格String value = "";if (null != cell) {switch (cell.getCellType()) {case HSSFCell.CELL_TYPE_NUMERIC: // 数值型if (HSSFDateUtil.isCellDateFormatted(cell)) {// 如果是Date类型则 ,获取该Cell的Date值value = HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toString();} else {// 纯数字,这里要判断是否为小数的情况,因为整数在写入时会被加上小数点String t = cell.getNumericCellValue()+ "";BigDecimal n = new BigDecimal(cell.getNumericCellValue());// 判断是否有小数点if (t.indexOf(".") < 0) {value = n.intValue() + "";} else {// 数字格式化对象NumberFormat nf = NumberFormat.getInstance();// 小数点最大两位nf.setMaximumFractionDigits(2);// 执行格式化value = nf.format(n.doubleValue());}}break;case HSSFCell.CELL_TYPE_STRING: // 字符串型value = cell.getRichStringCellValue().toString();break;case HSSFCell.CELL_TYPE_FORMULA:// 公式型// 读公式计算值value = String.valueOf(cell.getNumericCellValue());break;case HSSFCell.CELL_TYPE_BOOLEAN:// 布尔value = " " + cell.getBooleanCellValue();break;/* 此行表示该单元格值为空 */case HSSFCell.CELL_TYPE_BLANK: // 空值value = " ";break;case HSSFCell.CELL_TYPE_ERROR: // 故障value = " ";break;default:value = cell.getRichStringCellValue().toString();}} else {value = " ";}c.setCellValue(value);c.setCellStyle(style);}} else {HSSFCell c = r.createCell(0);c.setCellValue(" ");}}}} catch (Exception e) {e.printStackTrace();}// 这种写法不会产生临时文件,因为这里使用字节数组作为介质ByteArrayOutputStream os = new ByteArrayOutputStream();wb.write(os);byte[] content = os.toByteArray();InputStream is = new ByteArrayInputStream(content);return is;}public File[] getUpload() {return upload;}public void setUpload(File[] upload) {this.upload = upload;}public String[] getUploadContentType() {return uploadContentType;}public void setUploadContentType(String[] uploadContentType) {this.uploadContentType = uploadContentType;}public String[] getUploadFileName() {return uploadFileName;}public void setUploadFileName(String[] uploadFileName) {this.uploadFileName = uploadFileName;}}

 

 这里要关注的地方太多,具体的代码里注释写的很清楚。

一定要注意的是要判断单元格的类型,特别是数字类型时,我根据自己的需求一定了一些处理。

 

请您到ITEYE看我的原创:http://cuisuqiang.iteye.com

或支持我的个人博客,地址:http://www.javacui.com