#系统目录结构
com.huatech |--common 通用工具 | |--annotation 自定义注解 | |--constant 常量类 | |--export 导出工具类 | |--filter 过滤器 | |--freemarker.tag 自定义freemarker标签 | |--listener 监听器 | |--util 工具类 | |--controller |--dao |--domain |--model |--service
#导出相关类
com.huatech.common.annotation.EnumField 枚举属性注解,用于页面显示、导出等 com.huatech.common.export.ExportUtil excel 导出工具类 com.huatech.common.export.ExportModel Excel导出需要信息抽象接口 com.huatech.common.freemarker.tag.EnumFieldFormatterDirective 枚举属性freemarker标签 com.huatech.common.util.EnumFieldUtils 枚举属性JSON转换工具类
#实现步骤
1、添加导出相关类;
package com.huatech.common.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 枚举属性注解,用于页面显示、导出等 * 举例: public class SystemConfig { @EnumField(json="{ 1:启用, 0:未启用 }") private int status; ... } * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface EnumField { String json(); }
package com.huatech.common.export; import java.io.IOException; import java.math.BigDecimal; import java.net.URLEncoder; import java.sql.Timestamp; import java.util.Date; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFRichTextString; import com.github.pagehelper.PageHelper; import com.huatech.common.constant.ExportConstant; import com.huatech.common.util.BeanMapUtils; import com.huatech.common.util.EnumFieldUtils; /** * excel 导出工具类 * @author lh * @version 3.0 * @since 2017-5-22 * */ public class ExportUtil { private ExportUtil() { } public static void exportExcel(ExportModel exportModel, final HttpServletRequest request, final HttpServletResponse response) throws IOException { if(exportModel == null ){ throw new IllegalArgumentException("export model can not be null!"); } String exportTitle = request.getParameter(ExportConstant.PARAM_EXPORT_TITLE); String[] headers = request.getParameter(ExportConstant.PARAM_HEARDERS).split(","); String[] fields = request.getParameter(ExportConstant.PARAM_FIELDS).split(","); //create workbook Workbook wb = ExportUtil.createWorkbook(); //总记录数 int count = exportModel.getCount(); if(count == 0){//查询结果为空 Sheet sheet = wb.createSheet(exportTitle + "_1"); sheet = wb.getSheetAt(0); sheet.setDisplayGridlines(false);// 设置表标题是否有表格边框 createHeader(sheet, exportTitle, headers); }else{ for (int i = 0, j = getTotalPage(count); i < j; i++) { PageHelper.startPage(i+1, ExportConstant.DEFAULT_EXPORT_PAGE_SIZE, false); ExportUtil.exportExcel(exportTitle, headers, fields, i * ExportConstant.DEFAULT_EXPORT_PAGE_SIZE, wb, exportModel.getPageRecords()); } } ExportUtil.responseWorkbook(exportTitle, wb, request, response); } private static void exportExcel(String title, String[] headers, String[] fields, int startRow, Workbook wb, List<?> data) throws IOException { if(headers == null || headers.length == 0){ throw new RuntimeException("export headers must not be null"); } Sheet sheet = null; if(CollectionUtils.isEmpty(data)){ if(startRow == 0){ sheet = wb.createSheet(title + "_1"); sheet = wb.getSheetAt(0); sheet.setDisplayGridlines(false);// 设置表标题是否有表格边框 createHeader(sheet, title, headers); } return ; } startRow = startRow>0?startRow+2:startRow; int index = startRow, pageRowNo = startRow, columnCount = headers.length; // 行号、页码、列数 //枚举类型 Map<String, String> jsonMap = EnumFieldUtils.json2Map(data.get(0)); for (Object obj : data) { int sheetIndex = index/ExportConstant.SHEET_MAX_COUNT; if (index % ExportConstant.SHEET_MAX_COUNT == 0) { sheet = wb.createSheet(title + "_" + (sheetIndex + 1)); sheet = wb.getSheetAt(sheetIndex); sheet.setDisplayGridlines(false);// 设置表标题是否有表格边框 pageRowNo = 2; createHeader(sheet, title, headers); }else{ sheet = wb.getSheetAt(sheetIndex); } index++; @SuppressWarnings("unchecked") Map<String, Object> map = obj instanceof Map ? (Map<String, Object>) obj : BeanMapUtils.bean2Map(obj); Row nRow = sheet.createRow(pageRowNo++); // 新建行对象 for (int j = 0; j < columnCount; j++) { Cell cell = nRow.createCell(j); String field = fields[j]; Object val = map.get(field); if(jsonMap != null && jsonMap.containsKey(field)){ Object valObj = map.get(field); val = jsonMap.get(String.format(EnumFieldUtils.FIELD_MAP_KEY, field, isNull(valObj))); if (val == null) { val = isNull(valObj); } } setCellValue(sheet, cell, val); } } } /** * responseWorkbook * @param title * @param wb * @param request * @param response * @throws IOException */ private static void responseWorkbook(String title, Workbook wb,HttpServletRequest request, HttpServletResponse response)throws IOException{ String sFileName = title + ".xlsx"; // 火狐浏览器导出excel乱码 String agent = request.getHeader("User-Agent"); // 判断是否火狐浏览器 boolean isFirefox = agent != null && agent.contains("Firefox"); if (isFirefox) { sFileName = new String(sFileName.getBytes("UTF-8"), "ISO-8859-1"); } else { sFileName = URLEncoder.encode(sFileName, "UTF8"); } response.setHeader("Content-Disposition", "attachment; filename=".concat(sFileName)); response.setHeader("Connection", "close"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); //response.setHeader("Content-Type", "application/vnd.ms-excel"); wb.write(response.getOutputStream()); } /** * 设置单元格的值 * @param cell * @param cellVal */ private static void setCellValue(Sheet sheet, Cell cell, Object cellVal){ if(cellVal == null || String.class.equals(cellVal.getClass())){ cell.setCellValue(filterHref(cellVal)); }else if(Integer.class.equals(cellVal.getClass()) || int.class.equals(cellVal.getClass())){ cell.setCellValue(Integer.valueOf(cellVal.toString())); }else if(Long.class.equals(cellVal.getClass()) || long.class.equals(cellVal.getClass())){ cell.setCellValue(Long.valueOf(cellVal.toString())); }else if(Double.class.equals(cellVal.getClass()) || double.class.equals(cellVal.getClass())){ cell.setCellValue(Double.valueOf(cellVal.toString())); }else if(Float.class.equals(cellVal.getClass()) || float.class.equals(cellVal.getClass())){ cell.setCellValue(Float.valueOf(cellVal.toString())); }else if(BigDecimal.class.equals(cellVal.getClass())){ cell.setCellValue(NumberUtils.toDouble(cellVal.toString())); }else if(Date.class.equals(cellVal.getClass())){ cell.setCellValue(formatDateTime((Date)cellVal)); }else if(Timestamp.class.equals(cellVal.getClass())){ cell.setCellValue(formatDateTime((Timestamp)cellVal)); }else{ cell.setCellValue(isNull(cellVal)); } cell.setCellStyle(sheet.getWorkbook().getCellStyleAt(3)); } /** * 取得总页码数 * @param count * @return */ private static int getTotalPage(int count){ int pageSize = ExportConstant.DEFAULT_EXPORT_PAGE_SIZE; return (count % pageSize == 0) ? (count / pageSize) : (count / pageSize + 1); } /** * 将对象转为字符串 * * @param o * @return */ public static String isNull(Object o) { if (o == null) { return ""; } String str; if (o instanceof String) { str = (String) o; } else { str = o.toString(); } return str.trim(); } /** * 得到日期时间字符串,转换格式(yyyy-MM-dd HH:mm:ss) */ public static String formatDateTime(Date date) { return DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss"); } /** * 将对象转为字符串,去除超链接 * @param o * @return */ public static String filterHref(Object o) { if (o == null) { return ""; } String str; if (o instanceof String) { str = (String) o; } else { str = o.toString(); } return str.contains("href")?filterHtml(str):str; } /** * 过滤html标签 * @param input * @return */ public static String filterHtml(final String input){ String result = input; Pattern phtml = Pattern.compile("<[^>]+>", Pattern.CASE_INSENSITIVE); Matcher mhtml = phtml.matcher(result); result = mhtml.replaceAll(""); return result; } /** * 创建表头 * @param sheet * @param headers */ private static void createHeader(Sheet sheet, String title, String[] headers){ //设置标题 Row tRow = sheet.createRow(0); Cell hc = tRow.createCell(0); hc.setCellValue(new XSSFRichTextString(title)); sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.length - 1));// 合并标题行:起始行号,终止行号, 起始列号,终止列号 hc.setCellStyle(sheet.getWorkbook().getCellStyleAt(1)); //设置表头 Row nRow = sheet.createRow(1); for (int i = 0; i < headers.length; i++) { Cell cell = nRow.createCell(i); cell.setCellValue(headers[i]); cell.setCellStyle(sheet.getWorkbook().getCellStyleAt(2)); } } /** * 创建Workbook * @return */ private static Workbook createWorkbook(){ Workbook wb = new SXSSFWorkbook(100); CellStyle hcs = wb.createCellStyle(); hcs.setBorderBottom(BorderStyle.THIN); hcs.setBorderLeft(BorderStyle.THIN); hcs.setBorderRight(BorderStyle.THIN); hcs.setBorderTop(BorderStyle.THIN); hcs.setAlignment(HorizontalAlignment.CENTER); Font hfont = wb.createFont(); hfont.setFontName("宋体"); hfont.setFontHeightInPoints((short) 16);// 设置字体大小 hfont.setBold(true);// 加粗 hcs.setFont(hfont); CellStyle tcs = wb.createCellStyle(); tcs.setBorderBottom(BorderStyle.THIN); tcs.setBorderLeft(BorderStyle.THIN); tcs.setBorderRight(BorderStyle.THIN); tcs.setBorderTop(BorderStyle.THIN); Font tfont = wb.createFont(); tfont.setFontName("宋体"); tfont.setFontHeightInPoints((short) 12);// 设置字体大小 tfont.setBold(true);// 加粗 tcs.setFont(tfont); CellStyle cs = wb.createCellStyle(); cs.setBorderBottom(BorderStyle.THIN); cs.setBorderLeft(BorderStyle.THIN); cs.setBorderRight(BorderStyle.THIN); cs.setBorderTop(BorderStyle.THIN); Font font = wb.createFont(); font.setFontName("宋体"); font.setFontHeightInPoints((short) 12);// 设置字体大小 return wb; } public static void main(String[] args) { Workbook wb = ExportUtil.createWorkbook(); System.out.println(wb); } }
package com.huatech.common.export; import java.util.List; /** * Excel导出需要信息抽象接口 * * @author lh * */ public interface ExportModel { /** * 导出数据总记录数 * @return 数据总条数 */ int getCount(); /** * 查询指定页的数据 * * @return 页面数据 */ List<?> getPageRecords(); }
package com.huatech.common.freemarker.tag; import java.io.IOException; import java.io.Writer; import java.lang.reflect.Field; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.huatech.common.annotation.EnumField; import freemarker.core.Environment; import freemarker.template.TemplateDirectiveBody; import freemarker.template.TemplateDirectiveModel; import freemarker.template.TemplateException; import freemarker.template.TemplateModel; /** * 数据字典格式化自定义标签 在freemarker配置XML中定义为: * * <pre> * <property name="freemarkerVariables"> <map> <entry key="fieldFormatter" value-ref="enumFieldFormatterDirective" /> </map> </property> * </pre> * * 在页面使用例子: * * <pre> * <script type="text/javascript"> * <@fieldFormatter field="status" bean="com.huatech.domain.SystemConfig"/> * ........ * * //easyui columns formatter值为自定义标签中的fieldName+"Formatter" * {name:'status',label:'状态',sortable:false,formatter:statusFormatter} * * </script> * </pre> * * @author lh * @version 2.0 * @since 2017-05-22 * */ public class EnumFieldFormatterDirective implements TemplateDirectiveModel { private static final Logger LOGGER = LoggerFactory.getLogger(EnumFieldFormatterDirective.class); private String fieldName; @Override public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { String beanName = params.get("bean").toString(); fieldName = params.get("field").toString(); if (StringUtils.isBlank(fieldName) || StringUtils.isBlank(beanName)) { return; } // 查询字段指定分类所有条目 Class<?> clazz; try { clazz = Class.forName(beanName); Field fd = clazz.getDeclaredField(fieldName); EnumField enumField = fd.getAnnotation(EnumField.class); if (enumField != null) { Writer out = env.getOut(); StringBuilder buffer = new StringBuilder(); buffer.append(getJsonData( enumField.json())); buffer.append(createFormatterFunction()); out.write(buffer.toString()); } }catch (NoSuchFieldException | SecurityException e1) { LOGGER.error(e1.getMessage(), e1); } catch (ClassNotFoundException e1) { LOGGER.error(e1.getMessage(), e1); } } private String getJsonData(String json) { StringBuilder buffer = new StringBuilder(128); String objectName = fieldName + "Data_"; buffer.append("var " + objectName + " ={ \n"); String[] array = json.substring(1, json.length() - 1).split(","); for (String string : array) { String[] kv = string.split("\\:"); buffer.append("\t\"").append(kv[0].trim()).append("\" : \"").append(kv[1].trim()).append("\",\n"); } buffer.deleteCharAt(buffer.length() - 2); buffer.append("\n } ; \n"); return buffer.toString(); } private String createFormatterFunction() { StringBuilder buffer = new StringBuilder(50); String objectName = fieldName + "Data_"; buffer.append("function ").append(fieldName).append("Formatter(cellvalue,options,rowData){\n"); // 默认值为空字符串 buffer.append("\t if(cellvalue == null){\n"); buffer.append("\t\t return \" \"\n"); buffer.append("\t }\n"); buffer.append("\t var label= ").append(objectName).append("[cellvalue];\n"); buffer.append("\t if(!label) { \n"); buffer.append("\t\t return cellvalue ; \n"); buffer.append("\t } \n"); buffer.append("\t return label;\n "); buffer.append("}\n"); return buffer.toString(); } }
package com.huatech.common.util; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import com.huatech.common.annotation.EnumField; /** * 枚举属性JSON转换工具类 * * @author lh * @version 2.0 * @since 2017-05-19 */ public final class EnumFieldUtils { private static ConcurrentHashMap<String/* className */, Map<String/*fieldName_fieldValue*/, String/* fieldJsonValue */>> enumJsonCache = new ConcurrentHashMap<>(); public static final String FIELD_MAP_KEY = "%s_%s"; private EnumFieldUtils() { } public static Map<String, String> json2Map(Object obj) { if (obj != null) { Class<?> clazz = obj.getClass(); //类名称作为enumJsonCache的key String className = clazz.getName(); //取缓存 if (enumJsonCache.containsKey(className)) { return enumJsonCache.get(className); } synchronized (enumJsonCache) { //再次读取缓存 if (enumJsonCache.containsKey(className)) { return enumJsonCache.get(className); } Map<String, String> jsonMap = new HashMap<>(); do { // 得到类中的所有属性集合 Field[] fs = clazz.getDeclaredFields(); for (Field field : fs) { EnumField enumField = field.getAnnotation(EnumField.class); if (enumField != null) { jsonMap.putAll(convert(field.getName(), enumField.json())); } } clazz = clazz.getSuperclass(); } while (clazz != Object.class); enumJsonCache.put(className, jsonMap); return jsonMap; } } return new HashMap<>(); } /** * json转为Map对象 * * @param json * @return */ private static Map<String, String> convert(String fieldName, String json) { Map<String, String> map = new HashMap<>(); if (json == null || "".equals(json)) { return map; } map.put(fieldName, fieldName); String[] array = json.substring(1, json.length() - 1).split(","); for (String string : array) { String[] kv = string.split("\\:"); map.put(String.format(FIELD_MAP_KEY, fieldName, trim(kv[0])), trim(kv[1])); } return map; } /** * 去除字符串前后空格 * * @param str * @return */ public static String trim(String str) { if (str == null) { return ""; } return str.trim(); } }
2、在spring配置文件中配置枚举属性freemarker标签,本示例配置文件为spring-controller.xml
<bean id="enumFieldFormatterDirective" class="com.huatech.common.freemarker.tag.EnumFieldFormatterDirective"/> <property name="freemarkerVariables"> <map> <entry key="fieldFormatter" value-ref="enumFieldFormatterDirective" /> </map> </property>
3、页面使用枚举属性标签
<script type="text/javascript"> <@fieldFormatter field="status" bean="com.huatech.domain.SystemConfig"/> ... //easyui columns formatter值为自定义标签中的fieldName+"Formatter" {name:'status',label:'状态',sortable:false,formatter:statusFormatter} </script>
4、Controller层Excel导出
/** * 系统配置Excel导出 * @param model * @param request * @param response * @throws Exception */ @RequestMapping(value = "/modules/system/config/export" , method = RequestMethod.GET) public void exportSystemConfig(SystemConfigModel model, HttpServletRequest request, HttpServletResponse response)throws Exception { ExportUtil.exportExcel(new ExportModel() { private Map<String, Object> bean2Map(){ return BeanMapUtils.bean2Map(model); } @Override public int getCount() { return systemConfigService.getCount(bean2Map()); } @Override public List<?> getPageRecords() { return systemConfigService.findList(bean2Map()); } }, request, response); }
#导出功能示例
系统配置管理页面:http://localhost:[port]/modules/system/config/manage.html
[port]改为项目部署端口
相关推荐
在导出方面,POI能够根据业务需求生成包含大量数据的Excel文件,可以自定义样式、颜色、字体等,使得导出的文件既实用又美观。在批量导出时,尤其适用于需要将数据库查询结果或者处理后的数据以Excel形式分发给用户...
标题中的“自定义模板导出excle项目工具poi-el.rar”指的是一个使用Java的Apache POI库开发的项目,该工具允许用户自定义Excel模板来导出数据。Apache POI是一个流行的开源库,它使Java开发者能够读写Microsoft ...
标题中的"POI使用模板导出.zip"表明这是一个关于使用Apache POI库在Java中处理Excel模板并导出带有复杂表头(合并行和合并列)的案例。Apache POI是一个流行的开源库,专用于读取和写入Microsoft Office格式的文件,...
"根据poi导出excel能够正确运行"这个标题表明我们将讨论一个成功的POI实现,使得程序能够生成并正确运行Excel文件。 首先,我们需要理解Apache POI的基本概念。它提供了HSSF(Horizontally Stored Spreadsheet ...
首先,让我们深入理解"struts1"和"poi导出excel"这两个标签。Struts1是Apache软件基金会的一个开源MVC框架,它主要用于构建基于Java的Web应用程序。而Apache POI则是一个用于处理Microsoft Office文档的库,特别是...
标题 "poi导出excel并下载工具类(含有demo)" 提供了我们即将讨论的核心内容:使用Apache POI库来创建Excel文件,并提供一个下载功能。Apache POI是Java领域中广泛使用的库,用于处理Microsoft Office格式的文件,...
在实际开发中,你可能需要查看Apache POI的源代码来理解其内部工作原理,解决特定问题,或者实现自定义功能。例如,如果你发现POI默认的样式不能满足需求,可能需要查看和修改样式相关的源码。 **标签“工具”关联...
通过理解 Word 文档的 XML 结构和 POI 库的工作原理,我们可以自定义 XML 字符串,绕过 POI 的限制,实现上下型环绕和居中对齐的图片。这种方法虽然需要更多的代码和对 XML 结构的理解,但可以有效地解决 POI 在...
标题中的“poi导出Excel”指的是使用Apache POI库来创建和导出Excel文件的Java编程技术。Apache POI是一个开源项目,它提供了处理Microsoft Office格式文档的能力,包括Excel(.xlsx, .xls)。在Java应用程序中,POI...
下面我们将从标题、描述、标签以及部分内容中深入探讨 POI 导出 Excel 的关键知识点。 #### 一、Apache POI 简介 Apache POI 是一个用于读取和写入 Microsoft Office 文件格式(如Excel、Word)的纯Java库。POI ...
1. **初始化Workbook对象**:创建一个`XSSFWorkbook`实例,它是Apache POI针对Excel 2007及以上版本的Workbook实现。 2. **创建Sheet对象**:根据需要创建` XSSFSheet `实例,这代表Excel的工作表。 3. **设置水印...
标题中的“POI导出Excel”指的是Apache POI库在Java中用于读写Microsoft Office文档,特别是Excel文件的功能。Apache POI是一个开源项目,它允许开发者使用Java来创建、修改和显示微软的Office格式文件,如XLS和XLSX...
总结起来,"PIO的EXCEL的写入和导出"涉及的是使用编程方式(如Apache POI)来处理Excel文件,实现数据的导入和导出功能,这对于数据分析、报表生成和自动化流程等场景非常有用。实际操作中,开发者需要了解如何创建...
总的来说,poi-tl库为Java开发者提供了一个强大的工具,能够便捷地处理Word模板,实现内容替换,尤其适用于需要自定义生成大量Word文档的场景。掌握并熟练使用poi-tl,可以极大地提升文档处理的效率和灵活性。
【标签】"源码"提示我们可能需要关注POI的源代码分析和自定义功能开发。开发者可能会深入研究POI的源代码以了解其内部工作机制,或者根据特定需求进行扩展和定制。 "工具"标签则意味着POI是一个用于文件操作的实用...
下面将详细介绍jxls如何利用模板来实现Excel的导出。 1. **jxls概述**: jxls是一个Java库,它扩展了Apache POI,用于在Java应用中方便地处理Excel工作簿。它引入了一种基于模板的方法,使得动态创建和更新Excel...
本主题主要关注使用Apache POI和jxls库来实现这一功能,特别是针对不同版本的Excel(从2003到2010)的支持。 Apache POI是一个开源项目,它提供了Java API来创建、修改和显示Microsoft Office文件,包括Excel。POI...
总结来说,这个文档示例了如何使用Apache POI的SXSSF API高效地处理大量数据的Excel导出,避免内存溢出问题,同时提供了自定义样式以增强导出文件的视觉效果。在处理大数据时,这样的方法是必要的,因为它允许程序在...
总结起来,"Exce数据导入导出poijar"是一个Java库,它基于Apache POI,提供Excel数据的导入、导出及自定义功能,支持批量操作,可能还扩展到对Word文档的支持。这个库简化了Java开发中与Excel交互的过程,提高了数据...