Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类
Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类
==============================
©Copyright 蕃薯耀 2017年9月13日
http://www.cnblogs.com/fanshuyao/
直接上代码:
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import javax.servlet.ServletOutputStream; import org.apache.commons.lang.StringUtils; public class ExportUtil { /**
* 只导出包含在includeFieldNames中的属性
* @param sheetName 表格左下角的名称
* @param firstRowTitle 第一行需要设置的title,为空则不设置
* @param list 需要显示的数据集合
* @param headers 表格属性列名数组
* @param includeFieldNames 包含的实体属性
* @param widths 列的宽度,不设置(为Null)则默认,设置则根据对应的列宽设置(可以是一个,可以是对应的数量,整形数字,如200)
* @param outputStream 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
* @param datetimePattern 时间形式,当为空(Null或空字符串)时默认为yyyy-MM-dd HH:mm:ss
* @throws Exception
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> void exportExcel(String sheetName, String firstRowTitle, List<T> list, String[] headers, String[] includeFieldNames, Integer[] widths,
ServletOutputStream outputStream, String datetimePattern) throws Exception { // 默认输出格式
if (StringUtils.isBlank(datetimePattern)) {
datetimePattern = "yyyy-MM-dd HH:mm:ss";
} // 创建一个excel应用文件
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\"?>");
sb.append("\n");
sb.append("<?mso-application progid=\"Excel.Sheet\"?>");
sb.append("\n");
sb.append("<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"");
sb.append("\n");
sb.append(" xmlns:o=\"urn:schemas-microsoft-com:office:office\"");
sb.append("\n");
sb.append(" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"");
sb.append("\n");
sb.append(" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"");
sb.append("\n");
sb.append(" xmlns:html=\"http://www.w3.org/TR/REC-html40\">");
sb.append("\n"); sb.append("<Styles>\n"); /*设置列头样式*/
sb.append("<Style ss:ID=\"header\" ss:Name=\"header\">\n");//ss:ID=“header”对应下面的Row ss:StyleID=“header”
sb.append("<Interior ss:Color=\"#c4d79b\" ss:Pattern=\"Solid\"/>\n");// 设置背景颜色
sb.append("<Font ss:FontName=\"微软雅黑\" x:CharSet=\"134\" ss:Bold=\"Bolder\" ss:Size=\"12\"/>\n");//设置字体
sb.append("</Style>\n"); /*其它默认样式设置*/
sb.append("<Style ss:ID=\"Default\" ss:Name=\"Normal\">\n");
//sb.append("<Alignment ss:Vertical=\"Center\"/>\n");
sb.append("<Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\" ss:WrapText=\"1\"/>\n");// 左中右设置,一个是水平,一个是垂直
sb.append("<Borders>\n");
sb.append("<Border ss:Position=\"Left\" ss:LineStyle=\"Continuous\" ss:Color=\"#666\" ss:Weight=\"1\"/>\n");//左边框设置
sb.append("<Border ss:Position=\"Right\" ss:LineStyle=\"Continuous\" ss:Color=\"#666\" ss:Weight=\"1\"/>\n");//右边框设置
sb.append("<Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Color=\"#666\" ss:Weight=\"1\"/>\n");//下边框设置
sb.append("<Border ss:Position=\"Top\" ss:LineStyle=\"Continuous\" ss:Color=\"#666\" ss:Weight=\"1\"/>\n");//上边框设置
sb.append("</Borders>\n");
sb.append("<Font ss:FontName=\"宋体\" x:CharSet=\"134\" ss:Size=\"12\"/>\n");
sb.append("<Interior/>\n");
sb.append("<NumberFormat/>\n");
sb.append("<Protection/>\n");
sb.append("</Style>\n"); sb.append("</Styles>\n"); try { // 生成表格
int headersLength = headers.length; sb.append("<Worksheet ss:Name=\"" + sheetName + "\">");
sb.append("\n");
sb.append("<Table ss:ExpandedColumnCount=\"" + headersLength
+ "\" ss:ExpandedRowCount=\"1000000\" x:FullColumns=\"1\" x:FullRows=\"1\">");
sb.append("\n"); if(!StrUtils.isEmptyArray(widths)){
if(widths.length > 1){
for (int i = 0; i < headersLength; i++) {
sb.append("<Column ss:AutoFitWidth=\"0\" ss:Width=\""+widths[i]+"\"/>");
}
}else{
for (int i = 0; i < headersLength; i++) {
sb.append("<Column ss:AutoFitWidth=\"0\" ss:Width=\""+widths[0]+"\"/>");
}
}
} // 输出第一行的标题
if(!StrUtils.isBlank(firstRowTitle)){
//ss:StyleID可以加row或者Cell,加在Row,整行(包括空的Cell)都有,加上Cell,只有Cell才有。
sb.append("<Row ss:Height=\"30\">");
sb.append("<Cell ss:StyleID=\"header\" ss:MergeAcross=\""+ (headersLength - 1)+"\"><Data ss:Type=\"String\">" + firstRowTitle + "</Data></Cell>");
sb.append("</Row>");
} // 输出列头
sb.append("<Row>");
for (int i = 0; i < headersLength; i++) {
sb.append("<Cell ss:StyleID=\"header\"><Data ss:Type=\"String\">" + headers[i] + "</Data></Cell>");
}
sb.append("</Row>"); // 构建表体数据
for (int j = 0; j < list.size(); j++) { sb.append("<Row>"); T t = (T) list.get(j); for (int i = 0; i < includeFieldNames.length; i++) { // 获取属性名称
String fieldName = includeFieldNames[i]; String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); // 获取class对象
Class tCls = t.getClass(); // 获取属性值
Object value = null; try {
// 获取class方法
Method getMethod = tCls.getMethod(getMethodName, new Class[] {}); // 获取属性值
value = getMethod.invoke(t, new Object[] {}); } catch (NoSuchMethodException e) {
// 继续循环
continue;
} // 判断值的类型后进行强制类型转换
String textValue = "";
if (value instanceof Integer) {
// int value = ((Integer) value).intValue();
textValue = value.toString();
} else if (value instanceof String) {
// String s = (String) value;
textValue = value.toString();
} else if (value instanceof Double) {
// double d = ((Double) value).doubleValue();
textValue = String.format("%.2f", value);
} else if (value instanceof Float) {
// float f = ((Float) value).floatValue();
textValue = value.toString();
} else if (value instanceof Long) {
// long l = ((Long) value).longValue();
textValue = value.toString();
} else if (value instanceof Boolean) {
// boolean b = ((Boolean) value).booleanValue();
textValue = value.toString();
} else if (value instanceof Date) {
Date date = (Date) value;
SimpleDateFormat sdf = new SimpleDateFormat(datetimePattern);
textValue = sdf.format(date);
} else if ((value instanceof BigDecimal)) {
textValue = value.toString();
} else {
if (value != null) {
continue;
}
} sb.append("<Cell><Data ss:Type=\"String\">"); // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
if (StringUtils.isNotBlank(textValue)) { Pattern p = Pattern.compile("^//d+(//.//d+)?$");
Matcher matcher = p.matcher(textValue);
if (matcher.matches()) {
// 是数字当作double处理
sb.append(Double.parseDouble(textValue));
} else {
sb.append(textValue);
} } sb.append("</Data></Cell>"); } sb.append("</Row>");
sb.append("\n"); } sb.append("</Table>");
sb.append("<WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">");
sb.append("\n");
sb.append("<ProtectObjects>False</ProtectObjects>");
sb.append("\n");
sb.append("<ProtectScenarios>False</ProtectScenarios>");
sb.append("\n");
sb.append("</WorksheetOptions>");
sb.append("\n");
sb.append("</Worksheet>");
sb.append("</Workbook>");
sb.append("\n"); } catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} try {
outputStream.write(sb.toString().getBytes());
outputStream.flush();
outputStream.close();
sb = null;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
使用方式:
注意:不能直接通过Ajax请求,需要通过表单提交。
xml方式转Excel用到的属性:
补充一个:
ss:MergeAcross 表示跨列合并,如下:
注意是否需要减1,因为表示是跨多少列,那就是合并其它的几列,不包括自己,所以需要减 1
万能方法:
如果突然需要增加某些未知的属性,可以自己先创建一个Excel文件,做一个模板出来,然后另存为Xml文件,注意是Xml文件,保存后打开Xml文件查看自己创建的模板的某些属性应该怎么设置。但打开的xml文件比较乱,所以通过搜索找到自己对应的那个格子。
源码下载见:http://fanshuyao.iteye.com/blog/2393131
(如果你觉得文章对你有帮助,欢迎捐赠,^_^,谢谢!)
=============================
©Copyright 蕃薯耀 2017年9月13日
http://www.cnblogs.com/fanshuyao/
Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类的更多相关文章
- JAVA原始的导出excel文件,快捷通用 方便 还能够导出word文档哦
如今导出excel基本上都是用poi了,当报表格式非常负责的时候 开发难度会加大 假设报表有格式有变化 那就更复杂了,先发现一个非常老的技术.能够解决格式复杂的报表. 实例代码例如以下: <%@ ...
- Java中常用到的文件操作那些事(二)——使用POI解析Excel的两种常用方式对比
最近生产环境有个老项目一直内存报警,不时的还出现内存泄漏,导致需要重启服务器,已经严重影响正常服务了.获取生成dump文件后,使用MAT工具进行分析,发现是其中有个Excel文件上传功能时,经常会导致 ...
- 如何将一个Excel文件中的sheet移动到另外一个Excel?
背景 工作中往往会有多个excel维护的情况,随着业务的变化, 将一个Excel合并到另外一个Excel,成为必须. 如何移动sheet,对于不会的人,这是一个好问题, 也许你经过多次尝试都没有成功. ...
- 基于Java使用Flink读取CSV文件,针对批处理,多表联合两种方式Table类和Join方法的实现数据处理,再入CSV文件
Maven依赖 源头 <dependencies> <dependency> <groupId>org.projectlombok</groupId> ...
- JXL包大解析;Java程序生成excel文件和解析excel文件内容
最近需求变化,需要把excel导入 我以前没有做过,所以我查了一些资料 和参考别人的代码 以下是多种方式: import java.io.File; import java.io.FileInputS ...
- 【Java】使用Apache POI生成和解析Excel文件
概述 Excel是我们平时工作中比较常用的用于存储二维表数据的,JAVA也可以直接对Excel进行操作,分别有jxl和poi,2种方式. HSSF is the POI Project's pure ...
- Java 解析Excel文件为JSON
Excel转Json的需求 反正我对SSM基本不会的情况下来到现在这家公司,都是90后,感觉很好.第二天就给我开发任务,就是把用户上传的Excel文件转成JSON返回给前台用于大屏的数据展示. 解决方 ...
- Java文件操作系列[2]——使用JXL操作Excel文件
由于java流无法实现对Excel文件的读写操作,因此在项目中经常利用第三方开源的组件来实现.支持Excel文件操作的第三方开源组件主要有Apache的POI和开源社区的JXL. 总体来说,二者的区别 ...
- Java读写Excel文件,利用POI
直接看工具类代码吧, package com.example.demo.util; import com.example.demo.entity.ExcelDataVO; import org.apa ...
- PHP导出excel文件
现在教教你如何导入excel文件: 在我的文件储存里面有一个com文件夹的,将其解压放在ThinkPHP/Library/文件夹里面,然后就是写控制器啦!去调用这个插件: <?php names ...
随机推荐
- ThinkPHP使用阿里云通信短信服务
一.下载SDK 目前给出的SDK版本有JAVA.PHP.Python三个版本,我们使用PHP版本 二.文档结构 将下载的PHP-SDK解压,放入tp框架的Library目录下 发送短信主要使用api_ ...
- Python学习_09_模块
模块 模块是python中的最高组织单元,在物理层面上,模块以文件存储,模块的文件名就是模块的名字.py,每个模块都有自己的名称空间. python按照路径搜索来查找模块文件,在PYTHONPATH环 ...
- AspNet Core Web 应用程序的启动(有关 Program.cs类/ Startup.cs类 ) 当项目中干掉 Startup.cs 类如何设置启动 配置等等
.有关怎么创建Core MVC/API 这里就不说了,前段时间的博客有说过: 1. 项目生成后会有如图所示两个类 Program类Startup类 2. Startup类 初始内容 public ...
- Java学习笔记18(Object类)
Object类是Java中最顶层的父类,所有类都是它的子类,接口不继承它 Object类中的方法: 官方资料:boolean equals(Object obj) 指示其他某个对象是否与此对象&qu ...
- Java 与C++的各种优势与弱点--学习更新中
时隔两年没有怎么碰Java了,最近开始学习回顾下.在这里记录下学习的点滴,持续更新...希望对c++\java等不同语言有较为清晰的认识,至少不要学完以后,哪一个都不会了... Java 优势: 1. ...
- Java集合系列[1]----ArrayList源码分析
本篇分析ArrayList的源码,在分析之前先跟大家谈一谈数组.数组可能是我们最早接触到的数据结构之一,它是在内存中划分出一块连续的地址空间用来进行元素的存储,由于它直接操作内存,所以数组的性能要比集 ...
- 【干货分享】dos命令大全
一般来说dos命令都是在dos程序中进行的,如果电脑中安装有dos程序可以从开机选项中选择进入,在windows 系统中我们还可以从开始运行中输入cmd命令进入操作系统中的dos命令,如下图: 严格的 ...
- 2039: [2009国家集训队]employ人员雇佣
任意门 Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即 ...
- BZOJ:1185: [HNOI2007]最小矩形覆盖
1185: [HNOI2007]最小矩形覆盖 这计算几何……果然很烦…… 发现自己不会旋转卡壳,补了下,然后发现求凸包也不会…… 凸包:找一个最左下的点,其他点按照与它连边的夹角排序,然后维护一个栈用 ...
- Vijos P1448 校门外的树【多解,线段树,树状数组,括号序列法+暴力优化】
校门外的树 描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: K=1,K= ...