`
53873039oycg
  • 浏览: 843930 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

poi拼接xml导出Excel

    博客分类:
  • poi
 
阅读更多

       最近想使用写文本的方式导出Excel,首先想到的是Freemarker,可惜Excel 2007保存为(.*xml)时候报错了,保存为2003(.*xml)Excel打开报文件格式错误。如下

     

     而是转使用Jxls的:

    

<jx:forEach items="${dataList}" var="bo">
....
</jx:forEach>

    发现导出2万条数据直接oom了,而是放弃了这种方式。

    在poi自带的例子中发现了一个拼接xml导出Excel的代码,如下

    

     本人稍微修改了下,代码如下

     

package com.excel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.bean.ProductBo;

/**
 * 缺点:
 * 1)只适用Excel 07+
 * 2)单Sheet
 * 3)不能调整Excel行高和列宽
 * 4)不支持合并单元格
 * 5)不支持复杂类型
 */
public class WriteExcel07_S2_Test {
	public static void main(String[] args) throws Exception {
		WriteExcel07_S2_Test t = new WriteExcel07_S2_Test();
		XSSFWorkbook wb = new XSSFWorkbook();
		XSSFSheet sheet = wb.createSheet("测试导出");
		Map<String, XSSFCellStyle> styles = createStyles(wb);
		String sheetRef = sheet.getPackagePart().getPartName().getName();
		File tmpFile = new File("f:/saveFile/temp/template.xlsx");
		String resultFile = "f:/saveFile/temp/" + System.currentTimeMillis()
				+ ".xlsx";
		if (!tmpFile.exists()) {
			tmpFile.createNewFile();
		}
		FileOutputStream os = new FileOutputStream(tmpFile);
		wb.write(os);
		os.close();
		List<String> headList = t.generateExcelHeader();
		List<ProductBo> dataList = t.generateRandData(2000);
		long start = System.currentTimeMillis();
		File tmp = File.createTempFile("sheet", ".xml");
		Writer fw = new OutputStreamWriter(new FileOutputStream(tmp), "UTF-8");
		t.generateExcel(headList, dataList, fw, styles);
		fw.close();
		FileOutputStream out = new FileOutputStream(resultFile);
		t.substitute(tmpFile, tmp, sheetRef.substring(1), out);
		out.close();
		tmpFile.delete();
		System.out.println(System.currentTimeMillis() - start);
	}

	//拼接XML
	private void generateExcel(List<String> headList, List<ProductBo> dataList,
			Writer out, Map<String, XSSFCellStyle> styles) throws Exception {
		XSSFCellStyle stringStyle = styles.get("cell_string");
		XSSFCellStyle longStyle = styles.get("cell_long");
		XSSFCellStyle doubleStyle = styles.get("cell_double");
		XSSFCellStyle dateStyle = styles.get("cell_date");
		Calendar calendar = Calendar.getInstance();
		SpreadsheetWriter sw = new SpreadsheetWriter(out);
		
		sw.beginSheet();
		//表头
		sw.insertRow(0);
		int styleIndex = ((XSSFCellStyle) styles.get("sheet_title")).getIndex();
		for (int i = 0, len = headList.size(); i < len; i++) {
			sw.createCell(i, headList.get(i), styleIndex);
		}
		sw.endRow();
		
		int cellIndex = 0;
		for (int rownum = 1, len = dataList.size() + 1; rownum < len; rownum++) {
			cellIndex = 0;
			sw.insertRow(rownum);
			ProductBo bo = dataList.get(rownum - 1);
			Class<?> clz = bo.getClass();
			Field[] fields = clz.getDeclaredFields();
			Object val = null;
			Method fieldMethod = null;
			for (int k = 0, len2 = fields.length; k < len2; k++) {
				if ("serialVersionUID".equals(fields[k].getName())) {
					continue;
				}
				fieldMethod = (Method) clz.getMethod("get"
						+ getMethodName(fields[k].getName()));
				fieldMethod.setAccessible(true);// 不进行安全检测
				val = fieldMethod.invoke(bo);
				String typeName = fields[k].getGenericType().toString();
				if (typeName.endsWith("int") || typeName.endsWith("nteger")) {
					sw.createCell(cellIndex, (Integer) val,
							longStyle.getIndex());
				} else if (typeName.endsWith("ong")) {
					sw.createCell(cellIndex, (Long) val, longStyle.getIndex());
				} else if (typeName.endsWith("ouble")) {
					sw.createCell(cellIndex, (Double) val,
							doubleStyle.getIndex());
				} else if (typeName.endsWith("util.Date")) {
					calendar.setTime((java.util.Date) val);
					sw.createCell(cellIndex, calendar, dateStyle.getIndex());
				} else if (typeName.endsWith("sql.Date")) {
					calendar.setTime((java.sql.Date) val);
					sw.createCell(cellIndex, calendar, dateStyle.getIndex());
				} else {
					sw.createCell(cellIndex, val.toString(),
							stringStyle.getIndex());
				}
				cellIndex++;
			}
			sw.endRow();
		}
		sw.endSheet();
	}

	//表头
	private List<String> generateExcelHeader() {
		List<String> headList = new ArrayList<String>();
		headList.add("编号");
		headList.add("省");
		headList.add("市");
		headList.add("产品编码");
		headList.add("产品品牌");
		headList.add("产品型号");
		headList.add("产品成本");
		headList.add("优惠价");
		headList.add("当日销售数量");
		headList.add("当日销售小计");
		headList.add("本周销售数量");
		headList.add("本周销售小计");
		headList.add("本月销售数量");
		headList.add("本月销售小计");
		headList.add("是否结算");
		headList.add("统计时间");
		return headList;

	}

	private List<ProductBo> generateRandData(int num) {
		List<ProductBo> list = new ArrayList<ProductBo>(num * 3 / 2);
		for (int i = 1; i < num + 1; i++) {
			double price = new Random().nextInt(3000);
			ProductBo pb = new ProductBo(10000 + i, "北京", "北京", 2000 + i,
					"测试_S72" + i, "测试机型" + i, price,
					new Random().nextInt(5000), new Random().nextInt(30), price
							* new Random().nextInt(30),
					new Random().nextInt(100), price
							* new Random().nextInt(100),
					new Random().nextInt(300), price
							* new Random().nextInt(300), "是", new Date());
			list.add(pb);
		}
		return list;
	}

	//创建Excel样式
	private static Map<String, XSSFCellStyle> createStyles(XSSFWorkbook wb) {
		Map<String, XSSFCellStyle> stylesMap = new HashMap<String, XSSFCellStyle>();
		XSSFDataFormat fmt = wb.createDataFormat();
		XSSFCellStyle style = wb.createCellStyle();
		style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
		style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
		stylesMap.put("cell_string", style);
		XSSFCellStyle style2 = wb.createCellStyle();
		style2.setDataFormat(fmt.getFormat("0"));
		style2.setAlignment(XSSFCellStyle.ALIGN_CENTER);
		style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
		stylesMap.put("cell_long", style2);
		XSSFCellStyle style3 = wb.createCellStyle();
		style3.setDataFormat(fmt.getFormat("0.00"));
		style3.setAlignment(XSSFCellStyle.ALIGN_CENTER);
		style3.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
		stylesMap.put("cell_double", style3);
		XSSFCellStyle style4 = wb.createCellStyle();
		style4.setDataFormat(fmt.getFormat("yyyy-MM-dd"));
		style4.setAlignment(XSSFCellStyle.ALIGN_CENTER);
		style4.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
		stylesMap.put("cell_date", style4);
		XSSFCellStyle style5 = wb.createCellStyle();
		style5.setFillForegroundColor(IndexedColors.AQUA.getIndex());
		style5.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
		style5.setAlignment(XSSFCellStyle.ALIGN_CENTER);
		style5.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
		stylesMap.put("sheet_title", style5);
		return stylesMap;
	}

	//首字母大写
	private String getMethodName(String fildeName) throws Exception {
		byte[] items = fildeName.getBytes();
		items[0] = (byte) ((char) items[0] - 'a' + 'A');
		return new String(items);
	}

	//打包
	private void substitute(File zipfile, File tmpfile, String entry,
			OutputStream out) throws IOException {
		ZipFile zip = new ZipFile(zipfile);
		ZipOutputStream zos = new ZipOutputStream(out);
		Enumeration en = zip.entries();
		while (en.hasMoreElements()) {
			ZipEntry ze = (ZipEntry) en.nextElement();
			if (!ze.getName().equals(entry)) {
				zos.putNextEntry(new ZipEntry(ze.getName()));
				InputStream is = zip.getInputStream(ze);
				copyStream(is, zos);
				is.close();
			}
		}
		zos.putNextEntry(new ZipEntry(entry));
		InputStream is = new FileInputStream(tmpfile);
		copyStream(is, zos);
		is.close();
		zos.close();
		zip.close();
	}

	private static void copyStream(InputStream in, OutputStream out)
			throws IOException {
		byte[] chunk = new byte[1024];
		int count;
		while ((count = in.read(chunk)) >= 0)
			out.write(chunk, 0, count);
	}

	public static class SpreadsheetWriter {
		private final Writer _out;
		private int _rownum;

		public SpreadsheetWriter(Writer out) {
			this._out = out;
		}

		public void beginSheet() throws IOException {
			this._out
					.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?><worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">");
			this._out.write("<sheetData>\n");
		}

		public void endSheet() throws IOException {
			this._out.write("</sheetData>");
			this._out.write("</worksheet>");
		}

		public void insertRow(int rownum) throws IOException {
			this._out.write("<row r=\"" + (rownum + 1) + "\">\n");
			this._rownum = rownum;
		}

		public void endRow() throws IOException {
			this._out.write("</row>\n");
		}

		public void createCell(int columnIndex, String value, int styleIndex)
				throws IOException {
			String ref = new CellReference(this._rownum, columnIndex)
					.formatAsString();
			this._out.write("<c r=\"" + ref + "\" t=\"inlineStr\"");
			if (styleIndex != -1)
				this._out.write(" s=\"" + styleIndex + "\"");
			this._out.write(">");
			this._out.write("<is><t>" + value + "</t></is>");
			this._out.write("</c>");
		}

		public void createCell(int columnIndex, String value)
				throws IOException {
			createCell(columnIndex, value, -1);
		}

		public void createCell(int columnIndex, double value, int styleIndex)
				throws IOException {
			String ref = new CellReference(this._rownum, columnIndex)
					.formatAsString();
			this._out.write("<c r=\"" + ref + "\" t=\"n\"");
			if (styleIndex != -1)
				this._out.write(" s=\"" + styleIndex + "\"");
			this._out.write(">");
			this._out.write("<v>" + value + "</v>");
			this._out.write("</c>");
		}

		public void createCell(int columnIndex, double value)
				throws IOException {
			createCell(columnIndex, value, -1);
		}

		public void createCell(int columnIndex, Calendar value, int styleIndex)
				throws IOException {
			createCell(columnIndex, DateUtil.getExcelDate(value, false),
					styleIndex);
		}
	}
}

   bean:

  

package com.bean;

import java.util.Date;

public class ProductBo {
	private long id;
	private String provinceName;
	private String cityName;
	private long productNo;
	private String brandName;
	private String productName;
	private double costPrice;
	private double salePrice;
	private long todayNum;
	private double todayTotal;
	private long weekNum;
	private double weekTotal;
	private long monthNum;
	private double monthTotal;
	private String isSale;
	private Date doneDate;
	
	public ProductBo(long id, String provinceName, String cityName,
			long productNo, String brandName, String productName,
			double costPrice, double salePrice, long todayNum,
			double todayTotal, long weekNum, double weekTotal, long monthNum,
			double monthTotal, String isSale, Date doneDate) {
		super();
		this.id = id;
		this.provinceName = provinceName;
		this.cityName = cityName;
		this.productNo = productNo;
		this.brandName = brandName;
		this.productName = productName;
		this.costPrice = costPrice;
		this.salePrice = salePrice;
		this.todayNum = todayNum;
		this.todayTotal = todayTotal;
		this.weekNum = weekNum;
		this.weekTotal = weekTotal;
		this.monthNum = monthNum;
		this.monthTotal = monthTotal;
		this.isSale = isSale;
		this.doneDate = doneDate;
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getProvinceName() {
		return provinceName;
	}
	public void setProvinceName(String provinceName) {
		this.provinceName = provinceName;
	}
	public String getCityName() {
		return cityName;
	}
	public void setCityName(String cityName) {
		this.cityName = cityName;
	}
	public long getProductNo() {
		return productNo;
	}
	public void setProductNo(long productNo) {
		this.productNo = productNo;
	}
	public String getBrandName() {
		return brandName;
	}
	public void setBrandName(String brandName) {
		this.brandName = brandName;
	}
	public String getProductName() {
		return productName;
	}
	public void setProductName(String productName) {
		this.productName = productName;
	}
	public double getCostPrice() {
		return costPrice;
	}
	public void setCostPrice(double costPrice) {
		this.costPrice = costPrice;
	}
	public double getSalePrice() {
		return salePrice;
	}
	public void setSalePrice(double salePrice) {
		this.salePrice = salePrice;
	}
	public long getTodayNum() {
		return todayNum;
	}
	public void setTodayNum(long todayNum) {
		this.todayNum = todayNum;
	}
	public double getTodayTotal() {
		return todayTotal;
	}
	public void setTodayTotal(double todayTotal) {
		this.todayTotal = todayTotal;
	}
	public long getWeekNum() {
		return weekNum;
	}
	public void setWeekNum(long weekNum) {
		this.weekNum = weekNum;
	}
	public double getWeekTotal() {
		return weekTotal;
	}
	public void setWeekTotal(double weekTotal) {
		this.weekTotal = weekTotal;
	}
	public long getMonthNum() {
		return monthNum;
	}
	public void setMonthNum(long monthNum) {
		this.monthNum = monthNum;
	}
	public double getMonthTotal() {
		return monthTotal;
	}
	public void setMonthTotal(double monthTotal) {
		this.monthTotal = monthTotal;
	}
	public String getIsSale() {
		return isSale;
	}
	public void setIsSale(String isSale) {
		this.isSale = isSale;
	}
	public Date getDoneDate() {
		return doneDate;
	}
	public void setDoneDate(Date doneDate) {
		this.doneDate = doneDate;
	}
}

   结果为:

  

    调整格式后:

   

    这种方式导出几万还是很快的,缺点也有很多:

    1)只适用Excel 07+。
    2)单Sheet。
    3)不能调整Excel行高和列宽。
    4)不支持合并单元格。
     5)不支持复杂类型。

 

     上述的缺点没发现解决方法,欢迎指教。

     全文完

  

    

   

   

  • 大小: 82.9 KB
  • 大小: 263.2 KB
  • 大小: 373.7 KB
  • 大小: 81.4 KB
1
0
分享到:
评论

相关推荐

    poi3.8 doc,excel转html

    不过,需要注意的是,这里的代码可能不支持Microsoft Office 2007及更高版本使用的DOCX和XLSX格式,因为这些格式基于不同的XML结构,需要使用POI的HSSF(处理老版Excel)和XSSF(处理新版Excel)组件。如果需要处理...

    java导出excelxml.pdf

    在Java编程中,导出XML或Excel文件是常见的数据处理任务,特别是在大数据处理或报表生成的场景下。这里我们讨论的代码示例是通过Java来生成一个XML格式的文件,这个XML文件可以被Microsoft Excel识别并打开,就像一...

    java 使用POI合并两个word文档.docx

    在 appendBody 方法中,我们可以看到,使用 XmlOptions 对象设置了保存选项,然后使用 xmlText 方法将第二个文档的内容转换为字符串,最后将其追加到第一个文档中。 Java 使用 POI 合并两个 Word 文档的优点是: *...

    poi合并多个word文档并设置页码

    Apache POI是一个流行的Java库,专门用于处理Microsoft Office格式的文件,如Word、Excel和PowerPoint。在"poi合并多个word文档并设置页码"这个主题中,我们将深入探讨如何利用POI API来实现这两个功能。 首先,让...

    java导入excel表格

    Apache POI提供了HSSF(Horrible Spreadsheet Format)用于处理老版本的Excel(.xls)文件,以及XSSF(XML Spreadsheet Format)用于处理新版本的Excel(.xlsx)文件。在导入Excel表格时,我们需要根据文件格式选择...

    易语言-导出EXCEL模块

    二是利用开放的API或库,如Apache POI或OpenOffice SDK,来模拟Excel文件的行为。由于是从Delphi源码翻译过来的,我们可以推测这个模块可能利用了类似的技术,将Delphi中的Excel处理逻辑转换为易语言代码。 易语言...

    使用java代码实现excel的超链接

    总结,使用Java和Apache POI实现Excel超链接的关键步骤包括:引入POI库、创建Workbook和Sheet对象、生成超链接对象并将其设置到单元格,最后将工作簿写入文件。通过这种方式,我们可以为Excel文件增添互动性,提升...

    java以文本方式导出xlsx格式

    在Java编程环境中,导出大量数据到Excel(xlsx格式)是一项常见的任务,特别是在数据分析、报表生成和数据交换等场景中。传统的做法是使用Apache POI库来操作Excel文件,但这种方式处理大量数据时可能会遇到内存溢出...

    java 读取 doc docx word 中的内容 数据

    在开始之前,需要确保已经添加了Apache POI相关的依赖到项目中。如果使用Maven管理项目依赖,可以在`pom.xml`文件中加入以下依赖: ```xml &lt;groupId&gt;org.apache.poi &lt;artifactId&gt;poi &lt;version&gt;5.2.1 ...

    Java 添加Word项目符号、编号列表.zip

    第一个段落被关联到一个带有圆点项目符号的列表,而第二个段落则关联到一个编号列表。最后,我们通过`saveToFile`方法将修改后的文档保存为"Output/AddList.docx"。 这个压缩包中的"List_Doc"可能是包含上述代码...

    封装java常用工具的类

    4. **Excel导出**:Apache POI库是用于读写Microsoft Office格式文件的Java库,包括Excel。我们可以利用它创建、修改和读取Excel工作簿、工作表和单元格,支持数据格式化和样式设置。 5. **加密**:Java提供了强大...

    baomidou.zip + 根据数据库表生成mapper maven 包

    4. **整合到项目**:生成的Mapper接口和XML文件需要与Service层和Controller层进行整合,实现业务逻辑。 5. **测试验证**:生成的代码应通过单元测试来验证其正确性,确保所有操作都能正常工作。 Maven是一个项目...

    C#使用Nopi读写word

    通过遍历文档中的每一个段落,获取段落文本、样式以及段落中的所有`Run`对象,最后将文本拼接到一个`StringBuilder`对象中并返回。 #### 四、文档对象模型解析 无论是Word还是Excel,它们都有一套复杂的文档对象...

    java开发常用工具类.zip

    - 这可能是一个处理CSV或Excel文件的工具类,使用Apache POI库或者Java 8的CSV API来读取和写入表格数据。它可以简化表格数据的导入导出,支持数据的遍历、查找和修改。 4. **身份证工具类**: - 身份证工具类会...

    基于java开发的地图查找附件

    在Java开发领域,地图查找附件通常指的是利用Java编程语言实现的一种功能,允许用户在应用程序中搜索、定位和导航到地图上的特定位置。这种附件或组件可以集成到各种类型的软件中,如桌面应用、Web应用或者移动应用...

Global site tag (gtag.js) - Google Analytics