----------------------------------------------------------------------------------------------
[版权申明:本文系作者原创,转载请注明出处] 
文章出处: http://blog.csdn.net/sdksdk0/article/details/52557755
作者:朱培      ID:sdksdk0

--------------------------------------------------------------------------------------------

今天要分享的功能是一键上传excel文件,然后显示在页面中,以及将网页上的数据已excel文件的形式下载下来。使用的是Apache的POI,本文分享的实例是SSH框架完成的一个项目中的一个功能模块之一,使用了Maven,所以相关的jar包都贴出了maven的相关jar坐标。因为这个项目设计了很多ssh的配置,这里本文就不在一一列出,只写了关键的代码,文末提供源码下载,希望可以帮助到有需要的开发者。

一、POI简介

Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“可怜的模糊实现”。
Apache POI 是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。Apache POI 提供Java操作Excel解决方案(适用于Excel97-2008)。

网址是http://poi.apache.org/,我们可以通过添加maven倚赖的方式下载,poi的坐标是:

     <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency>

二、实例准备

页面效果如下:

(这里的数据我是随便写的,仅作为参考数据,不是真实数据)

通过点击页面上的批量导入按钮,可以实现界面无刷新一次性导入写好的数据。我们先excel中准备好数据:注意的是在excel中的数字都要改为文本格式的,不能是“常规",否则导入会失败的。

三、一键上传

jsp页面代码:

需要先导入:jquery.ocupload-1.1.2.js

然后再页面中给你的按钮的id添加upload的方法。  (以下片段在文末项目中的位置是:/BOS/src/main/webapp/WEB-INF/pages/base/region.jsp)

     // 对批量导入添加一键上传效果 $('#button-import').upload({name : 'upload', action : '${pageContext.request.contextPath}/region_OCimport', // 表单提交路径onComplete : function(response){var data = eval("("+response+")");$.messager.alert('信息',data.msg,'info');$('#grid').datagrid('reload');}});

这个我转到的是Action中:

这里的话我就是加了pinyin4j来将汉字转为拼音,这样的话做的就是简码了;

在pom.xml中添加maven依赖:(以下片段在文末项目中的位置是:/BOS/pom.xml)

     <dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.0</version></dependency>

在Action中处理:(以下片段在文末项目中的位置是:/BOS/src/main/java/cn/tf/bos/web/action/bc/RegionAction.java)

//接收上传的数据public String OCimport() throws IOException{// 1、 工作薄对象HSSFWorkbook hssfWorkbook = new HSSFWorkbook(new FileInputStream(upload));// 解析工作薄hssfWorkbook.setMissingCellPolicy(Row.CREATE_NULL_AS_BLANK); // 避免空指针异常// 2、 获得SheetHSSFSheet sheet = hssfWorkbook.getSheetAt(0); // 获得第一个sheet// 3、遍历每一行for (Row row : sheet) {if (row.getRowNum() == 0) {continue;}// 从第二行 开始解析Region region = new Region();String id = row.getCell(0).getStringCellValue(); // 获得第一个单元格信息if (id.trim().equals("")) {// id 无值,跳过continue;}region.setId(id);region.setProvince(row.getCell(1).getStringCellValue());region.setCity(row.getCell(2).getStringCellValue());region.setDistrict(row.getCell(3).getStringCellValue());region.setPostcode(row.getCell(4).getStringCellValue());//使用pinyin4j生成编码和简码String str=region.getProvince()+region.getCity()+region.getDistrict();str=str.replaceAll("省", "").replaceAll("市", "").replaceAll("区", "").replaceAll("县", "");String[]  arr=PinYin4jUtils.getHeadByString(str);StringBuffer sb = new StringBuffer();for (String headChar : arr) {sb.append(headChar);}region.setShortcode(sb.toString()); // 简码// 生成城市编码region.setCitycode(PinYin4jUtils.hanziToPinyin(region.getCity(), ""));//保存数据时出错try {regionService.saveRegion(region);} catch (Exception e) {// 导入region失败,记录日志LOG.error("区域导入失败,编号:" + region.getId(), e);}}//返回jsonMap<String,Object>  map=new HashMap<String,Object>();map.put("result", "success");map.put("msg", "区域导入完成");ActionContext.getContext().put("map", map);return "OCimport";}private File upload;public void setUpload(File upload) {this.upload = upload;}

汉字转换为拼音的工具类为:(以下片段在文末项目中的位置是:/BOS/src/main/java/cn/tf/bos/utils/PinYin4jUtils.java)

public class PinYin4jUtils {/*** 将字符串转换成拼音数组* * @param src* @return*/public static String[] stringToPinyin(String src) {return stringToPinyin(src, false, null);}/*** 将字符串转换成拼音数组* * @param src* @return*/public static String[] stringToPinyin(String src, String separator) {return stringToPinyin(src, true, separator);}/*** 将字符串转换成拼音数组* * @param src* @param isPolyphone*            是否查出多音字的所有拼音* @param separator*            多音字拼音之间的分隔符* @return*/public static String[] stringToPinyin(String src, boolean isPolyphone,String separator) {// 判断字符串是否为空if ("".equals(src) || null == src) {return null;}char[] srcChar = src.toCharArray();int srcCount = srcChar.length;String[] srcStr = new String[srcCount];for (int i = 0; i < srcCount; i++) {srcStr[i] = charToPinyin(srcChar[i], isPolyphone, separator);}return srcStr;}/*** 将单个字符转换成拼音* * @param src* @return*/public static String charToPinyin(char src, boolean isPolyphone,String separator) {// 创建汉语拼音处理类HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();// 输出设置,大小写,音标方式defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);StringBuffer tempPinying = new StringBuffer();// 如果是中文if (src > 128) {try {// 转换得出结果String[] strs = PinyinHelper.toHanyuPinyinStringArray(src,defaultFormat);// 是否查出多音字,默认是查出多音字的第一个字符if (isPolyphone && null != separator) {for (int i = 0; i < strs.length; i++) {tempPinying.append(strs[i]);if (strs.length != (i + 1)) {// 多音字之间用特殊符号间隔起来tempPinying.append(separator);}}} else {tempPinying.append(strs[0]);}} catch (BadHanyuPinyinOutputFormatCombination e) {e.printStackTrace();}} else {tempPinying.append(src);}return tempPinying.toString();}public static String hanziToPinyin(String hanzi) {return hanziToPinyin(hanzi, " ");}/*** 将汉字转换成拼音* * @param hanzi* @param separator* @return*/public static String hanziToPinyin(String hanzi, String separator) {// 创建汉语拼音处理类HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();// 输出设置,大小写,音标方式defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);String pinyingStr = "";try {pinyingStr = PinyinHelper.toHanyuPinyinString(hanzi, defaultFormat,separator);} catch (BadHanyuPinyinOutputFormatCombination e) {// TODO Auto-generated catch blocke.printStackTrace();}return pinyingStr;}/*** 将字符串数组转换成字符串* * @param str* @param separator*            各个字符串之间的分隔符* @return*/public static String stringArrayToString(String[] str, String separator) {StringBuffer sb = new StringBuffer();for (int i = 0; i < str.length; i++) {sb.append(str[i]);if (str.length != (i + 1)) {sb.append(separator);}}return sb.toString();}/*** 简单的将各个字符数组之间连接起来* * @param str* @return*/public static String stringArrayToString(String[] str) {return stringArrayToString(str, "");}/*** 将字符数组转换成字符串* * @param str* @param separator*            各个字符串之间的分隔符* @return*/public static String charArrayToString(char[] ch, String separator) {StringBuffer sb = new StringBuffer();for (int i = 0; i < ch.length; i++) {sb.append(ch[i]);if (ch.length != (i + 1)) {sb.append(separator);}}return sb.toString();}/*** 将字符数组转换成字符串* * @param str* @return*/public static String charArrayToString(char[] ch) {return charArrayToString(ch, " ");}/*** 取汉字的首字母* * @param src* @param isCapital*            是否是大写* @return*/public static char[] getHeadByChar(char src, boolean isCapital) {// 如果不是汉字直接返回if (src <= 128) {return new char[] { src };}// 获取所有的拼音String[] pinyingStr = PinyinHelper.toHanyuPinyinStringArray(src);// 创建返回对象int polyphoneSize = pinyingStr.length;char[] headChars = new char[polyphoneSize];int i = 0;// 截取首字符for (String s : pinyingStr) {char headChar = s.charAt(0);// 首字母是否大写,默认是小写if (isCapital) {headChars[i] = Character.toUpperCase(headChar);} else {headChars[i] = headChar;}i++;}return headChars;}/*** 取汉字的首字母(默认是大写)* * @param src* @return*/public static char[] getHeadByChar(char src) {return getHeadByChar(src, true);}/*** 查找字符串首字母* * @param src* @return*/public static String[] getHeadByString(String src) {return getHeadByString(src, true);}/*** 查找字符串首字母* * @param src* @param isCapital*            是否大写* @return*/public static String[] getHeadByString(String src, boolean isCapital) {return getHeadByString(src, isCapital, null);}/*** 查找字符串首字母* * @param src* @param isCapital*            是否大写* @param separator*            分隔符* @return*/public static String[] getHeadByString(String src, boolean isCapital,String separator) {char[] chars = src.toCharArray();String[] headString = new String[chars.length];int i = 0;for (char ch : chars) {char[] chs = getHeadByChar(ch, isCapital);StringBuffer sb = new StringBuffer();if (null != separator) {int j = 1;for (char ch1 : chs) {sb.append(ch1);if (j != chs.length) {sb.append(separator);}j++;}} else {sb.append(chs[0]);}headString[i] = sb.toString();i++;}return headString;}
}

在struts.xml中配置返回:(以下片段在文末项目中的位置是:/BOS/src/main/resources/struts.xml)

     <action name="region_*"  class="regionAction"  method="{1}"><result  name="OCimport" type="json"><param name="root">map</param></result>   </action>

这样的话就全部实现了上传的功能了。

四、文件下载

接下来说一下下载的功能:

例如我们要将这个页面中的内容变为excel文件下载下来。

在下载的jsp页面中:

点击按钮触发这个下载的函数,我们有一个函数:点击后跳转到action中。(以下片段在文末项目中的位置是:/BOS/src/main/webapp/WEB-INF/pages/base/subarea.jsp)

 function doExport(){location.href="${pageContext.request.contextPath}/subarea_exportFile";}

在action中:(以下片段在文末项目中的位置是:/BOS/src/main/java/cn/tf/bos/web/action/bc/SubareaAction.java)

 public String exportFile() throws IOException{// 对文件名进行编码String downloadFileName = "分区数据.xls";// 获得用户使用浏览器类型String agent = ServletActionContext.getRequest().getHeader("user-agent");// 对下载文件名编码downloadFileName = FileUtils.encodeDownloadFilename(downloadFileName, agent);// 将结果放入值栈ActionContext.getContext().put("downloadFileName", downloadFileName);return "exportFile";}//文件下载流public InputStream  getInputStream() throws IOException{PageResponseBean pageResponseBean=(PageResponseBean) ServletActionContext.getRequest().getSession().getAttribute("pageResponseBean");List<Subarea>  subareas=pageResponseBean.getRows();HSSFWorkbook  hssfWorkbook=new HSSFWorkbook();HSSFSheet sheet=hssfWorkbook.createSheet("分区数据");HSSFRow  headRow=sheet.createRow(0);headRow.createCell(0).setCellValue("分区编号");headRow.createCell(1).setCellValue("关键字");headRow.createCell(2).setCellValue("起始号");headRow.createCell(3).setCellValue("结束号");headRow.createCell(4).setCellValue("是否区分单双号号");headRow.createCell(5).setCellValue("位置信息");// 向excel写数据for (Subarea subarea : subareas) {// 每个分区一行HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);dataRow.createCell(0).setCellValue(subarea.getId());dataRow.createCell(1).setCellValue(subarea.getAddresskey());dataRow.createCell(2).setCellValue(subarea.getStartnum());dataRow.createCell(3).setCellValue(subarea.getEndnum());dataRow.createCell(4).setCellValue(subarea.getSingle());dataRow.createCell(5).setCellValue(subarea.getPosition());}// 将数据缓存到字节数组ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();hssfWorkbook.write(arrayOutputStream);arrayOutputStream.close();byte[] data = arrayOutputStream.toByteArray();// 再通过字节数组输入流读取数据return new ByteArrayInputStream(data);}

在struts.xml中配置:

<result name="exportFile"  type="stream"><param name="contentType">application/vnd.ms-excel</param><param name="contentDisposition">attachment;filename=${downloadFileName}</param></result>

这样我们就可以把数据下载出来了:

总结:文本使用的都是非常经典的技术来实现了文件一键上传、汉字转拼音、文件上传、文件下载的功能,具有非常好的实际意义,属于开发者必备技能之一。

项目地址:https://github.com/sdksdk0/BOS

文件一键上传、汉字转拼音、excel文件上传下载功能模块的实现相关推荐

  1. python xlrd读取文件报错_python利用xlrd读取excel文件始终报错原因

    1.代码按照网上百度的格式进行书写如下: 但运行后,始终报错如下: 百度了xlrd网页: 分明支持xls和xlsx两种格式的文件,但运行始终报错. 最后找到原因是因为我所读取的文件虽然是以.xls命名 ...

  2. catia制作物料明细_CATIA导出装配文件的部件列表BOM清单到Excel文件 | 坐倚北风

    在CATIA中可以导出装配文件的部件列表BOM清单到Excel文件.点击Design Table命令按钮. 打开Creation of a Design Table对话框,选择Create a des ...

  3. Python提取Word文件中的目录标题保存为Excel文件

    from docx import Document from openpyxl import Workbook from openpyxl.styles import Alignment, Borde ...

  4. 使用matlab处理INCF采集数据,mdf(.dat)格式文件,并将将其写入excel文件

    使用matlab处理INCF采集数据,mdf(.dat)格式文件,并将将其写入excel文件 最近在做某汽车公司关于汽车标定的数据.数据通过INCA采集,保存为.dat格式.数据可以通过measure ...

  5. c语言创建excel文件6,怎么利用c语言创建excel文件

    怎么利用c语言创建excel文件 想要利用c语言创建excel文件再把它导入excel其实很简单,如果数据简单的话,可以使用CSV(逗号分隔值)格式的文件.CSV格式的文件可以用OfficeExcel ...

  6. python3读取excel汉字_从excel文件python3读取汉字

    我有一个Excel文件,包含两列,第一列是中文,第二列只是一个链接. 我试了两种方法.但是它不起作用,我也无法在控制台中打印值,我将settings(pycharm)中的编码变量更改为U8,仍然不起作 ...

  7. python文件处理系列(二):Excel文件读取库xlwings

    一.xlwings概述 1.xlwings特点 xlwings能够非常方便的读写Excel文件中的数据,并且能够进行单元格格式的修改 可以和matplotlib以及pandas无缝连接 可以调用Exc ...

  8. Python 获取当前文件夹所有文件名并写入到excel文件中

    在工作中,有时候,我们需要整理文件夹中的所有文件名称,并罗列在一张表格中.天哪,我的文件夹中有上千个文件,要一个个的复制粘贴吗?太麻烦了吧?今天,我们用Python来解决这个问题. 1. 使用方法: ...

  9. python怎么打开excel文件并处理_Python利用openpyxl处理Excel文件(Excel文件基本操作)...

    上一篇,我们简要介绍了openpyxl及其安装过程,这一篇我们学习使用openpyxl处理Excel的具体过程,力争涵盖大多数官方文档中相关内容,对这一知识点进行简单的汇总. 一.学习目标 (一)op ...

  10. 小白用python处理excel文件-python高手之路python处理excel文件(方法汇总)

    python3处理Excel文件的实际应用谢谢时光大盗把小编的时间偷走让小编没有时间去想你. 最近遇到个问题,使用python处理Excel文件.如何将表格中数据读取以后以而小编使用的是python3 ...

最新文章

  1. 编写yara规则 检测恶意软件
  2. 在什么场景下该使用JMX,如何使用,会带来什么好处,这种场景下有哪些替代方案?...
  3. 学习Git的最佳资料
  4. 在64位的linux中运行32位的应用程序
  5. Saving Tang Monk II HihoCoder - 1828(2018北京网络赛三维标记+bfs)
  6. opacity用法:
  7. Sring类型数组赋值
  8. 163邮箱:退信代码(对照表) - 说明篇
  9. 怎么恢复linux定时器任务,定时操作 crontab at 以及恢复定时操作
  10. [概念学习] Virtualization的几个概念
  11. 听说你决定当全职自由漏洞猎人了?过来人想跟你聊聊
  12. 【机器学习】径向基(RBF)神经网络的tensorflow实现
  13. sbt命令行常用命令
  14. Excel函数实战技巧精粹(五)LEN和LENB等函数之常用用法
  15. 大数据之HBase 实战微博系统 完整使用 (第六章)
  16. Word2Vec模型之实现篇
  17. 数据结构:线性表的顺序存储结构,实现集合的交差并补
  18. Linux有问必答:如何在Linux命令行中刻录ISO或NRG镜像到DVD
  19. 多示例论文泛读:Revisiting Multiple Instance Neural Networks (2016 mi-Net MI-Net)
  20. 很强大,并且易于使用,更重要的是免费的一个分区工具:分区助手

热门文章

  1. APS计划排程和生产排产系统,包含哪些排程算法?
  2. 教育系统APP(四)
  3. 如何将纸质书怎么弄成电子版?如何将纸质文档变成电子文档,下面教你方法
  4. 只工作不玩耍,聪明的孩子也变傻
  5. 教你如何在Mac上打开CAJ格式的文件
  6. css插件载进去ps里面,CSS3Ps(ps图层插件)官方版
  7. Centos Siege测试使用
  8. 自学4年多 Github 上斩获 90k Star! 聊聊自学习编程的正确姿势!
  9. 安卓7.0 安兔兔 作假修改
  10. 教你如何在github上提交代码(Window10示例,内含2021年github提交机制的更新变动)