`

用Apache POI导出Excel的改进

    博客分类:
  • OA
阅读更多

上文中使用的导出Excel方法提到上文的方法会导致同步操作的问题(即当某一个用户点击生成Excel链接后,执行生成"text.xls" 后,正准备往外面输出文件,就在这时,另一用户又点击了同一个链接,这就导致了一个严重的问题,也就是当某一用户正要往外输出流的时候,另一个用户正准备 创建这个流或者正要写这个流! ),解决这个问题有两个方式:一是将临时文件命名为一个随机名字的文件,这会导致服务器的临时文件会增加(原方法是在程序中写死文件名,所以只会存在一个文件,这也是发生同步问题的根本原因),所以如果使用这个方法需要定期的删除这些文件,删除这些文件又有两种方式,一是在用户下载完成后再删除这些临时文件,另一个是写一个线程,隔一段时间后就将文件删除,后者无疑更好,因为很难去判断用户什么时候下载完成该文件,同时也要注意存在当用户已经下载但程序还没有来得及删除,服务器就已经停掉的情况,所以还要写一个Servlet在服务器启动的时候把这些没有来得及删除的文件删除掉;二是根本不生成临时文件,在导出Excel的程序中,直接将Apache poi中生成的WorkBook对象转换成InputStream流,这无疑是最好的方式

 

第一种方式:

1、JAVA Service代码:

public InputStream getInputStream() {
		HSSFWorkbook wk = new HSSFWorkbook();
		HSSFSheet sheet = wk.createSheet("UserList");
		HSSFRow row = sheet.createRow(0);
		
		HSSFCell cell = row.createCell((short)0);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("序号");
		
		cell = row.createCell((short)1);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("姓");
		
		cell = row.createCell((short)2);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("名");
		
		cell = row.createCell((short)3);
		cell.setEncoding(HSSFCell.ENCODING_UTF_16);
		cell.setCellValue("年龄");
		
		List<User> userList = this.getUserList();
		
		for(int i=0;i<userList.size();++i){
			User user = userList.get(i);
			row = sheet.createRow(i+1);
			
			cell = row.createCell((short)0);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getId());
			
			cell = row.createCell((short)1);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getFirstname());
			
			cell = row.createCell((short)2);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getLastname());
			
			cell = row.createCell((short)3);
			cell.setEncoding(HSSFCell.ENCODING_UTF_16);
			cell.setCellValue(user.getAge());
		}
//		//此处对文件进行了命名,但是下载时的文件默认名字实际上是struts.xml中配置的名字,
//		//此文件是在tomcat服务器中bin目录中的临时文件的名字
//		File file = new File("test.xls");
		
		final File file = new File(new StringBuffer(StringUtil.getRandomString(10)).append(".xls").toString());
		
		try {
			OutputStream os = new FileOutputStream(file);
			wk.write(os);
			os.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		InputStream is=null;
		try {
			is = new FileInputStream(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		new Thread(new Runnable() {
			public void run() {
				try {
					Thread.sleep(7000);//7秒钟
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				file.delete();
			}
		}).start();
		
		return is;
	}

 取得随机字符串除了自己写的外还可以使用common-lang包中的org.apache.commons.lang.RandomStringUtils来获得

2、Servlet的代码:

@SuppressWarnings("serial")
public class DeleteExcelServlet extends HttpServlet {
	public void init() throws ServletException {
		//取得当前路径,当服务器的bin路径
		File file = new File(".");
		//第一种删除方法
		File[] fileList = file.listFiles();
		for(File f : fileList){
			if(f.getName().endsWith("xls")){
				f.delete();
			}
		}
		//第二种删除写法
//		File[] fileList = file.listFiles(new FileFilter() {
//			public boolean accept(File pathname) {
//				if(pathname.getName().endsWith("xls")){
//					return true;
//				}
//				return false;
//			}
//		});
//		for(File f : fileList){
//			f.delete();
//		}
	}
}

 需在web.xml中配置load-on-startup属性,且无须配置url-mapping,因为无须用户访问同时也没有写doGet等方法

使用上面的方法在弹出下载提示框的时候,如果选择的不是下载,而是点击打开按钮,这时会在tomcat的bin目录产生两个Excel文件,一个是在对话框出来之前产生的,一个是在点击打开后产生的,而如果这时点的是保存,则不会再产生这个多余的文件,很明显这是跟我们的操作有关的,且产生了两条sql语句,说明service方法被调用了两次。造成这个问题的原因是因为跟浏览器碰到可下载链接时的处理方式有关,当浏览器遇到一个可下载的请求的时候,它有两种选择,一种是在当前浏览器将要下载的文件打开,另一种选择是弹出一个下载对话框,而根据上一往篇文章,我并没有显式配置它,所以struts使用的是默认的配置方式,即inline的方式,也就是第一种方式,这也就是导成这个问题的原因,将struts.xml文件修改如下:

<action name="generateExcel" class="userAction" method="generateExcel">
			<!-- 指定type为stream类型 -->
			<result name="success" type="stream">
				<!-- 指定输出的为Excel文件 -->
				<param name="contentType">application/vnd.ms-excel</param>
				<!-- 指定下载时文件的默认名字,注貌似不能使用中文,同时filename不能写成fileName -->
				<param name="contentDisposition">attachment;filename="AllUser.xls"</param>
				<!-- 此处的值是对应于action中的某个返回值为InputStream的方法,如为下面的配置,
					那么 userAction中需要有一个public InputStream getDownloadFile()的方法 -->
				<param name="inputName">downloadFile</param>
			</result>
</action>

 在

<param name="contentDisposition">attachment;filename="AllUser.xls"</param>

中添加了attachment的属性

如果不声明,它会是这样的:

<param name="contentDisposition">inline;filename="AllUser.xls"</param>

改后仍有可能依然会出现两个xls文件,这有可能是迅雷的对浏览器下载的自动探测造成的,把它的这个功能关闭,即可发现成功。

 

 

 

分享到:
评论

相关推荐

    使用ITEXT导出PDF、WORD,APACHE POI导出EXCEL报表文件

    本文将深入探讨如何使用ITEXT库导出PDF和Word,以及利用Apache POI库导出Excel报表文件。 首先,让我们来了解ITEXT库。ITEXT是一个开源Java库,专门用于创建和修改PDF文档。使用ITEXT,你可以方便地生成包含文本、...

    Apache poi 导出excel实例

    这篇博客文章“Apache POI 导出excel实例”将深入探讨如何使用Apache POI库来生成Excel文件,这对于在Java环境中处理大量数据并需要导出为Excel格式的应用非常有用。 首先,我们需要导入Apache POI库到我们的项目中...

    apache POI 导出Excel 设置打印

    在使用Apache POI导出Excel时,首先需要创建一个`XSSFWorkbook`对象作为工作簿,然后通过工作簿创建`XSSFSheet`对象代表工作表。例如: ```java XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet =...

    Apache Poi Excel导出

    这篇博客“Apache Poi Excel导出”可能详细介绍了如何使用Apache POI库来生成Excel文件,特别适用于数据导出或报表生成等场景。 Apache POI API 包含多个关键组件,如HSSF(Horizontally Stored Format)用于处理旧...

    apache poi 导出excel、word

    2. **导出Excel**: 使用Apache POI创建Excel文件时,首先需要创建一个Workbook对象,它是Excel文件的容器。然后,可以添加Sheet对象来表示工作表,并在Sheet中创建Row和Cell来填充数据。POI支持多种单元格数据类型...

    POI导出Excel文件

    以下是一个简化的示例,演示了如何使用POI导出Excel: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.io....

    poi导出根据模板导出excel和简单列表导出excel源码

    在本案例中,我们关注的是如何使用 Apache POI 库来导出 Excel 文件,特别是根据模板导出和简单列表导出。下面将详细介绍这个过程。 1. **Apache POI 概述** Apache POI 提供了 Java API 来读写 Microsoft Office ...

    Apache POI 模板导出excel.rar

    在"Apache POI 模板导出excel.rar"这个压缩包中,我们聚焦于使用Apache POI 3.16版本来生成基于Excel模板的数据导出功能。这个过程涉及到多个关键知识点,下面将详细阐述。 1. **Apache POI库**:Apache POI是一个...

    POI使用Excel模板文件循环输出行并导出Excel

    在这个特定的例子中,我们将讨论如何使用POI库基于一个Excel模板文件循环输出数据行,并将结果导出为新的Excel文件。 首先,我们需要理解POI库的基本概念。POI提供了HSSF(Horizontally SpreadSheet Format)和XSSF...

    POI导出Excel表格

    在这个“POI导出Excel表格”的实例中,我们将深入探讨如何利用Apache POI进行Excel文件的导入与导出操作。 首先,我们需要在项目中集成Apache POI库。如果你使用的是Maven,可以在pom.xml文件中添加以下依赖: ```...

    POI的EXCEL导出,自动换行

    通过以上步骤,我们成功地实现了使用Apache POI在Java中导出Excel文件,并实现了自动换行的功能。这种方式不仅可以提高工作效率,还能确保数据的准确性和完整性。 #### 六、注意事项与优化建议 - **兼容性问题**:...

    poi导出excel需要的jar

    "poi导出excel需要的jar"指的是在使用Apache POI进行Excel导出时,你需要包含特定的JAR依赖文件。 首先,要实现POI导出Excel的功能,你需要下载Apache POI相关的JAR文件。这些文件通常包括以下核心组件: 1. **poi...

    基于Apache POI导出大数据量(百万级)Excel的实现

    【作品名称】:基于Apache POI导出大数据量(百万级)Excel的实现 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:...

    poi导出excel需要包

    使用Apache POI导出Excel的步骤大致如下: 1. **引入依赖**:首先,你需要将下载的Apache POI JAR文件添加到你的项目类路径中,如果是Maven或Gradle项目,可以添加相应的依赖配置。 2. **创建工作簿对象**:使用...

    poi导出excel表格

    本教程将详细讲解如何使用Apache POI在Web环境中导出Excel表格,避免生成不必要的临时文件,从而优化系统资源管理。 一、Apache POI简介 Apache POI 是一个开源项目,它提供了Java API来处理Microsoft的Office格式...

    使用poi方式导出excel(分多个sheet导出)

    七、导出Excel文件 最后,将Workbook写入OutputStream或File,完成导出: ```java try (FileOutputStream out = new FileOutputStream("output.xlsx")) { workbook.write(out); } catch (IOException e) { e....

    Java实现POI导出Excel

    以上就是使用Java和Apache POI导出Excel的基本步骤。实际应用中,你可能还需要处理更复杂的情况,如合并单元格、添加公式、读取数据等。POI库提供了丰富的API来支持这些功能,使得在Java中操作Excel文件变得相当便捷...

    java poi导出excel

    以上就是使用Java POI导出Excel的基本步骤。你可以根据实际需求调整代码,例如添加数据遍历、样式设置、图表生成等功能。确保正确管理资源,避免内存泄漏,特别是在服务器端处理大量数据时。记得在完成后关闭工作簿...

    poi导出excel demo

    在本示例中,"poi导出excel demo"指的是使用Apache POI库创建和导出Excel文件的演示。这个项目可能包含了一个或多个Java源代码文件,展示了如何使用POI API来生成Excel工作簿、工作表、单元格等内容。 Apache POI ...

Global site tag (gtag.js) - Google Analytics