一、Excel基本导出

1、 默认模板目录的配置

可以通过配置文件配置一个模板的目录来获取目录中的模板,当然这不是必须的,只是为了统一代码管理。

1.1 非web工程配置

在classpath:目录下smile.properties文件中配置 export.templateDir属可以是绝对路也可以是相对路径:

例如:

export.templateDir=${user.dir}/src/

例如:

export.templateDir=D:/template

1.2 Web项目配置

web项目的时候除可在smile.properties中配置外,还实现了另一种可以在web.xml文件中的配置,此方法与其它使用listener加载配置的原理一致

例如:

<context-param>

<param-name>xlsTemplateFileDir</param-name>

<param-value>/WEB-INF/xlsTemplate</param-value>

</context-param>

也可以是classpath下

<context-param>

<param-name>xlsTemplateFileDir</param-name>

<param-value>classpath:xlsTemplate</param-value>

</context-param>

再配置一个listener加载配置

<listener>

<listener-class>org.smile.report.excel.XlsExportWebSupportListener</listener-class>

</listener>

1.3 配置信息使用

在配置的templateFileDir 目录下创建模板一个导出模板。

使用方法    XlsExportTemplate.getFilePath("/vmi/deliveryGoods.xls")  来获取模板的路径

代码样例:

XlsExportTemplate temp = new XlsExportTemplate();

try {

temp.loadXlsTemplate(XlsExportTemplate.getFilePath("/vmi/deliveryGoods.xls"));

setReponseXls("VMI送货单_",".xls");

List list=DeliveryQueryUtil.queryPageDeliery(vmiDeliveryService, query);

temp.fillDataSource(list);

BufferedOutputStream os = new BufferedOutputStream(getResponse().getOutputStream());

temp.write(os);

os.flush();

os.close();

} catch (Exception e) {

e.printStackTrace();

}

设置模板样例:

2、Excel模板

通用的模板样式为第一个sheet页中设置导出信息,第一行为导出信息的名称,第二行为导出信息对应导出对象的字段名。

2.1 对应字段名

如要显示名称 在单元格中 输入 name

如果属性是一个象则使用“ . ” 的方式调用,如 : id.name

属性可以支持 List     如  sublist.name  则会循环显示 对象sublist 中的对象的name 属性

2.2 转换函数

如果需要对对象属性进行转换,可以注册函数来处理

实现 org.smile.report.excel.Function 接口

package org.smile.report.excel;

public abstract class Function{

/**

* 转换对象值

* @param oneData 行对象

* @param exp 表达式

* @param expValue 字段值

* @return

*/

public abstract Object convert(Object oneData,String exp,Object expValue);

/**

* 是否需要字段的值

* 当返回false时 convert方法中expValue是不会有值的

* 返回true时convert方法中expValue会根据exp表达式的值从oneData中获取值

* @return

*/

public boolean needFieldValue(){

return true;

}

}

注册后 ,模板中 使用 函数名{字段名} 方式调用。

如:

temp.registerFunction("f", new Function() {

@Override

public Object convert(Object oneData, String exp,

Object expValue) {

ReportQuery reportData=(ReportQuery)oneData;

String status=reportData.getVstatus();

if(StringUtils.isEmpty(status)){

return "未确认";

}else if("5".equals(status)){

return "待采购确认";

}else if("0".equals(status)){

return "已确认";

}

});

在excel单元格中填写 f{status} 就会调用转换函数进行显示转换

2.3显示常量

如需在xls中显示常量 可以通过 /**增加一个参数*/

public void addParam(String name,Object value)

方法添加常量  在模板中 以#name 方式调用

例如:

XlsExportTemplate temp=new XlsExportTemplate();

temp.addParam("china", "中华人民共和国");

在单元格中输入#china   输出的内容为中华人民共和国

2.4 Ognl表达式支持

导出模板中还可以对ongl表达式支持,只需要将ognl.jar加载到classpath中,在单元格中使用${exp} 或 ognl{exp} 方式对ognl表达式支持输出

例${state==1?'成功':'失败'}    对ognl的使用请参考网上的资料

2.5 内部变量

导出模板中还支持对 XlsExportTemplate 的成员变量进行输出显示,使用##fieldName 方式进行输出显示

/** 当前数据填充到的序号 */

protected int dataRowNumber = 1;

##dataRowNumber 可会输出当前填充到的数据行号

/** 数据的长度 */

protected int dataSize;

二、Excel导出高级特性

1、数据填充行

数据填充行是可以设置的,只是在默认情况下是行二行,第一行为描述,当不是第二行的时候需要在代码中设置。

/**

* 设置 数据填充名称行号

* @param dataNameRowIndex

*/

public void setDataNameRowIndex(int dataNameRowIndex) {

this.dataNameRowIndex = dataNameRowIndex;

}

例如:

XlsExportTemplate temp = new XlsExportTemplate();

temp.setDataNameRowIndex(4); temp.loadXlsTemplate(temp.getFilePath("/vmi/deliveryGoodsNo.xls"));

此模板就是以第5行做为填充数据行,所以设置索引的时候是4

2、填充数据行后的内容

有的时候在填充数据行后面的行还需要固定内空的行的时候,现要在代码中设置模板底部的索引和底部行数。

/**

* 设置页脚信息

* @param bottomRowIndex 页脚开始行索引

* @param rowCount 页脚行数

*/

public void setBottomRowIndex(int bottomRowIndex, int rowCount) {

this.bottomRowIndex = bottomRowIndex;

this.bottomRowEnd = bottomRowIndex + rowCount-1;

}

使用代码如下:

XlsExportTemplate temp = new XlsExportTemplate();

setReponseXls("机加工送货单_",".xls");

temp.loadXlsTemplate(temp.getFilePath("/auinf/auinfDeliveryNote.xls"));

temp.setDataNameRowIndex(8);

temp.setBottomRowIndex(28, 7);

模板:

3、存在头信息和尾信息

需要导出的模板存在头信息和尾信息的情况

3.1例子

XlsExportTemplate template=new XlsExportTemplate();

try {

List list=new LinkedList();

for(int i=0;i<2;i++){

for(int j=0;j<2;j++){

for(int k=0;k<2;k++){

Map map=new HashMap();

map.put("a", "A"+i);

map.put("b", "B"+i);

map.put("c", "C"+j);

map.put("d", k);

list.add(map);

}

}

}

template.setMergeConfig(new MergeConfig(new String[]{"a"}, new String[]{"a","${b+1}","b"}));

template.addMergeConfig(new MergeConfig(new String[]{"a","c"}, new String[]{"c"}));

Map context=new HashMap();

context.put("dataSource", list);

template.setDataNameRowIndex(5);

template.setBottomRowIndex(6, 3);

context.put("name", "广东迈瑞");

context.put("date", DateUtils.parseDate("2017-09-08"));

CellImage image= new CellImage(new FileInputStream("D:/temp/test.jpg"),Workbook.PICTURE_TYPE_JPEG);

image.setWidth(3.5F);

image.setHeight(1f);

image.setLeft(10);

image.setTop(20);

context.put("image",image);

template.loadXlsTemplate("d:/temp/test.xls");

template.addParam("ttt", "胡真山");

template.registerFunction("ff", new Function(){

@Override

public Object convert(Object oneData, String exp, Object expValue) {

return "测试";

}

});

template.fillDataSource(context);

3.2模板

3.3输出

4、插入图片

通过代码在要输出的对象中加入图片对象,在模板中跟输出普通字段属性一个设置即可

代码:

CellImage image= new CellImage(new FileInputStream("D:/temp/test.jpg"),Workbook.PICTURE_TYPE_JPEG);

image.setWidth(3.5F);

image.setHeight(1f);

image.setLeft(10);

image.setTop(20);

context.put("image",image);

在模板中只要设置 ${image} 就会输出为图片

5、单元格合并

在template中添加合并配置即会对单元格行进行合并

template.addMergeConfig(new MergeConfig(new String[]{"a","c"}, new String[]{"c"}));

上面的代码实现了:a 和 c 的值相同的行 对 c 列进行合并

5.1 MergeConfig 类的代码

package org.smile.report.excel;

import java.util.HashMap;

import java.util.Map;

import org.smile.report.poi.ObjectMergeSet;

/**

* 设置要合并的列

* @author 胡真山

*/

public class MergeConfig extends ObjectMergeSet{

/***

* 要合并的列名

*/

protected String[] mergeName;

protected Map<String,Integer> nameIndex=new HashMap<String,Integer>();

/**

* @param keyName

* @param mergeColumn 要合并的列的索引

*/

public MergeConfig(String keyPropertyName, Integer[] mergeColumn){

this.propertyName=new String[]{keyPropertyName};

this.mergeColumn=mergeColumn;

}

/**

* 以标题名称来标记合并

* @param keyName

* @param mergeName

*/

public MergeConfig(String keyPropertyName, String[] mergeName){

this.propertyName=new String[]{keyPropertyName};

this.mergeName=mergeName;

}

/**

* @param keyName

* @param mergeColumn 要合并的列的索引

*/

public MergeConfig(String[] keyPropertyName, Integer[] mergeColumn){

this.propertyName=keyPropertyName;

this.mergeColumn=mergeColumn;

}

/**

* 以标题名称来标记合并

* @param keyName

* @param mergeName

*/

public MergeConfig(String[] keyPropertyName, String[] mergeName){

this.propertyName=keyPropertyName;

this.mergeName=mergeName;

}

/**

* 从xls的标题初始化出要合并的列的索引

* @param names

*/

protected void initMerge(String[] names,int firstCellNum){

initNameIndex(names);

if(mergeColumn==null){

initMergeColumn(names,firstCellNum);

}

}

public Integer getColumnIndex(String name){

return nameIndex.get(name);

}

protected void initNameIndex(String[] names){

int i=0;

for(String n:names){

nameIndex.put(n, i++);

}

}

protected void initMergeColumn(String[] names,int firstCellNum){

mergeColumn=new Integer[mergeName.length];

int i=firstCellNum;

for(String n:mergeName){

Integer idx=nameIndex.get(n);

if(idx==null){

throw new NullPointerException("不存在的数据名称列:"+n);

}

mergeColumn[i]=idx;

i++;

}

}

}

6、自定义行的高度

通过方法重写实现高度的自定义。

例子:

/**

* 通过一定策略对行高度进行控制

* @author 胡真山

*

*/

protected class ExportContractTemplete extends XlsExportTemplate{

private float keyRowHeight;

private float rate;

private float height;

@Override

protected Row onCreateDataRow(Sheet sheet, Row keyRow, Object rowData, int rowIndex) {

Row row=super.onCreateDataRow(sheet, keyRow, rowData, rowIndex);

if(rowIndex==dataNameRowIndex){

keyRowHeight=keyRow.getHeightInPoints();

rate=40f/dataSize;

if(rate>2.5){

rate=2.5f;

}else if(rate<0.8){

rate=0.8f;

}

height=keyRowHeight*rate;

}

if(dataSize<20){

TDacContractDetail obj=(TDacContractDetail)rowData;

int length=obj.getMaktx().length();

if(obj.getMaktx().length()>20){

float nrate=(length/10)*0.8f;

if(nrate>5){

nrate=5;

}else if(nrate<2.5){

nrate=2.5f;

}

row.setHeightInPoints(keyRowHeight*nrate);

}else{

row.setHeightInPoints(height);

}

}else{

row.setHeightInPoints(height);

}

return row;

}

}

7、多sheet页填充

org.smile.report.excel .XlsExportTemplateUtils中定义了一个多sheet页填充数据,从第一个sheet页复制模板,进行数据填充。

/**

* 一次填充多页数据

* @param template

* @param contexts

* @param nameHandler

*/

public static void fillDataSource(XlsExportTemplate template,Map<String,Object>[] contexts,SheetNameHandler nameHandler){

int index=0;

int sheetIndex=1;

for(Map<String,Object> context :contexts){

if(index>1){

template.copySheet(0, nameHandler);

template.setSheetIndex(sheetIndex++);

template.fillDataSource(context);

}

index++;

}

//填充第一个sheet

template.setSheetIndex(0);

template.fillDataSource(contexts[0]);

}

8、在模板中配置属性

可以在第一行第一列单元格中配置模板表头和表尾信息,配置了之后在代码中就不需要使用代码对这几个属性进行设置了。

如下图:

9、动态模板

在代码中使用setDynamic 方法设置动态列,在模板中使用 %[name] 的方式设置动态列

代码示例:

XlsExportDynamicTemplate template=new XlsExportDynamicTemplate();

try {

template.loadXlsTemplate("d:/temp/dynamic.xls");

template.setDynamic("names", new String[]{"二月","三月","四月"});

template.setDynamic("ms", new String[]{"m2","m3","m4"});

template.setDynamic("names2", new String[]{"五月","六月","七月"});

template.setDynamic("ms2", new String[]{"m5","m6","m7"});

List list=new LinkedList();

for(int i=0;i<10;i++){

Map map=new HashMap();

map.put("m1", 10);

map.put("m2", 20);

map.put("m3", 30);

map.put("m4", 40);

map.put("m5", 50);

map.put("m6", 60);

map.put("m7", 70);

map.put("total", 8000);

list.add(map);

}

template.fillDataSource(list);

template.write(new FileOutputStream(new File("d:/temp/dynameic_out.xls")));

} catch (IOException e) {

e.printStackTrace();

}

模板样例:

 

输出结果:

三、Excel导入

1、基本导入

1.1代码样例

final String batchFlag=UUIDGenerator.uuid();

XlsImportTemplete template=new XlsImportTemplete(upload){

@Override

protected Object newTargetInstanse() {

TDacDelayPaymentTemp obj=new TDacDelayPaymentTemp();

obj.setBatchFlag(batchFlag);

return obj;

}

@Override

protected void onAfterReadRow(Object targetObject, Row currentRow) {

TDacDelayPaymentTemp obj=(TDacDelayPaymentTemp)targetObject;

Date date=DateUtils.parseDate(obj.getImportDate());

Date latestFeedbackDate=DateUtils.getBeforeDay(date, -29);

obj.setLatestFeedbackDate(DateUtils.formatOnlyDate(latestFeedbackDate));

obj.setImportDate(DateUtils.formatOnlyDate(date));

}

@Override

protected boolean validateTitles() throws ExcelException{

String[] t=new String[]{"月份","序号","报关单号","报关合同号","币种","进口金额","进口日期"};

if(ArrayUtils.check(getTitles(), new int[]{0,1,2,3,4,5,6}, t)){

return true;

}else{

throw new ExcelException("请选择正确的模板"+(titleRowIndex+1)+"行必须为标题:"+JSONValue.toJSONString(t));

}

}

};

template.initTargetClass(TDacDelayPaymentTemp.class);

List<TDacDelayPaymentTemp> list=template.readDataToList(CollectionUtils.newLinkedHashMap(new Integer[]{0,1,2,3,4,5,6},

new String[]{"month","serialNum","customsNo","contractNo","currency","importMoney","importDate"}));

模板样例

1.2 简单样例

XlsImportTemplete importTemplate=new XlsImportTemplete(upload);

importTemplate.initTargetClass(TDacHkStockDetail.class);

List<TDacHkStockDetail> dataList=importTemplate.readDataToList(CollectionUtils.newLinkedHashMap(

new Integer[]{6,1,2,3,4,5,8,9,10,11,12,13,14,15},

new String[]{"quantity","lifnr","matnr","model","brand","producePlace","grossWeight","netWeight","boxNum","batchNo","checkindate","deliveryNo","unit","remark"}));

1.3 List 属性支持

可以对导入类有list属性支持 ,list属性必须有getter setter 和泛型。xls属性以第一列做为是否是同一个对象的区分 ,就是说第一列同一个对象第二行只能为空,合并后不影响

public List<TestVo> getSubList();

这们就可以在xls中设置 subList.name   这样就会把单元格的值导入到subList 属性中的对象的name 属性中

四、其它Excel操作工具

1、PoiSupport

org.smile.report.poi.PoiSupport 类是一个poi库操作的工具类,提供了一此方便的功能。

转载于:https://my.oschina.net/huzhsh/blog/1816768

Excel导入导出功能相关推荐

  1. SpringBoot中使用Easyexcel实现Excel导入导出功能(三)

    导出的数据包含有图片 导出excel表格的数据包含有图片,这种场景比较少.通Easyexcel实现这样的需求,我认为最简便的方法就是使用前面提到的自定义转换器(com.alibaba.excel.co ...

  2. SpringBoot中使用Easyexcel实现Excel导入导出功能(一)

    目录 前言 1.常规导入 2.读取到指定的列 3.读取全部的sheet页 4.日期.数字及其他自定义格式的转换 5.表头有多行的表格读取 6.表头数据的读取 7.单元格内的备注内容读取 前言 exce ...

  3. SpringBoot 项目实现 Excel 导入导出功能

    背景 Excel 导入与导出是项目中经常用到的功能,在 Java 中常用 poi 实现 Excel 的导入与导出.由于 poi 占用内存较大,在高并发下很容易发生 OOM 或者频繁 fullgc,阿里 ...

  4. tiptop使用java的poi包实现EXCEL导入导出功能

    4gl可以调用java的poi包实现EXCEL的导入导出,今天分享一个EXCEL导入的功能!  一:环境搭建  1:poi文件导入  首先下载POI文件(找不到的可以私信我),解压后上传到ERP的服务 ...

  5. SpringBoot 项目优雅实现 Excel 导入导出功能

    背景 Excel 导入与导出是项目中经常用到的功能,在 Java 中常用 poi 实现 Excel 的导入与导出.由于 poi 占用内存较大,在高并发下很容易发生 OOM 或者频繁 fullgc,阿里 ...

  6. VUE的Excel导入导出功能

    在做人力资源管理的后台项目时,实现了excel表的导入导出功能.用到了vue-element-admin提供的框架(链接地址 ),我们只需要在自己的项目中封装改造即可. 项目中实现excel表的导入与 ...

  7. 【飞秋】ASP.NET 之 常用类、方法的超级总结,并包含动态的EXCEL导入导出功能,奉上类库源码

    最近闲了,花点几天时间将项目中常用的一些类.方法做了一下总结,希望对大家有用. 实用类:UtilityClass 包含如下方法 判断对象是否为空或NULL,如果是空或NULL返回true,否则返回fa ...

  8. 前端 - excel导入 / 导出功能

    1. 导入功能 1.1 前端主导(工作大量在前端) 上传excel文件,把excel文件的内容读出来,还原成最基本的行列结构,按后端的接口要求回传过去. 前端读excel文件,调接口 1.2 后端主导 ...

  9. vue中实现Excel导入导出功能

    导入Excel功能 前置条件: 依赖包xlsx npm install xlsx -S 这里提供一个现成的在vue中导入Excel的功能(原作者-花裤衩),代码在最下面,可直接复制. 创建一个文件夹, ...

  10. 若依框架内自带的excel导入导出功能

    若依这个框架非常的神la奇ji,每次我想加入某个功能的时候都会报一些奇奇怪怪的错,其他项目里能用的代码复制粘贴过来就报错,然后逛一下官网发现官网已经集成了,然后用他官方集成的就不报错.就只许用你的不许 ...

最新文章

  1. win设置计算机网络,Win10怎么修改网络类型,Win10网络类型怎么设置?
  2. linux pwm 调屏_基于嵌入式Linux的LCD背光调节及驱动的实现
  3. Git Bash Cmd命令笔记
  4. bat文件注册为Windows服务与依赖关系设置
  5. 3月25日 JavaScript
  6. python全栈开发要学些什么_如何迅速学习Python 全栈开发?
  7. oracle method_opt,统计量收集Method_Opt参数使用(下)
  8. why approver preview in Document builder is empty
  9. 2018年11月12日
  10. hadoop之blockreport
  11. MySql PreparedStatement用法 及 Transaction处理
  12. java web 数据库操作_Java Web----Java Web的数据库操作(二)
  13. 用Eclipse写java
  14. 【matplotlib笔记】plt.subplot()绘制子图
  15. python小程序100题-python 练习题:流量套餐订购小程序
  16. [USACO08MAR]Land Acquisition
  17. Linkedin第三方登录集成(android)
  18. java 图片下载爬虫_java入门爬虫(爬取网页的图片下载到本地磁盘)
  19. 大疆M3508电机使用CAN通信进行速度PID闭环控制详解
  20. C#界面设计--5--Bitmap.save保存图片时: GDI+ 中发生一般性错误 解决办法

热门文章

  1. 2022-2028全球及中国双输入RTD温度计行业研究及十四五规划分析报告
  2. 定位神器:1秒定位DOM元素绑定的事件代码的位置
  3. SAP BASIS ADM100 中文版 Unit 7(1)
  4. Python学习手册之函数和模块
  5. S3(Simple Storage Service) 对象存储 详细介绍
  6. SAT数学:必背公式之三角函数
  7. 【修真院“正直”系列之三】【修真神界】【修行卷】【第一章】修真院入场券...
  8. Java 实战:桌球小游戏
  9. java web应用开发期末考试_JavaWeb期末考试A卷
  10. Python图像处理笔记——形态学处理(skimage.morphology)