POI操作EXCEL实战

一、POI概述

Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

结构:

  • HSSF - 提供读写Microsoft Excel格式档案的功能。
  • XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。

HSSF 常用于处理.xls(带宏/VBA的表格)
XSSF 常用于处理.xlsx (不带宏/VBA的表格)

  • HWPF - 提供读写Microsoft Word格式档案的功能。
  • HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
  • HDGF - 提供读写Microsoft Visio格式档案的功能。

在这里我们以HSSF为例,进行介绍。

我们需要实现的功能是:
已经存在一个.xls的excel模板存放在本地,我们需要拿到这个模板,根据用户的不同,在上面动态写入用户信息,并从数据库中取出一堆信息,作为模板中某列单元格点击时触发弹框的内容,让用户可以在弹框中复选想要得信息。然后后台校验用户上传的表格,如果有错误,返回错误信息;没有错误,则存入数据库。

二、实战代码


//1. 找到我们存放模板的路径
//注:File.separator 与系统相关的分隔符字符,以方便在不同系统都能运行
String pathFrom = ".." + File.separator + "webserver" + File.separator + "webapps" + File.separator + "portal" + File.separator + "apps" + File.separator + AppIdConstant.APPID + File.separator + "model" + File.separator + "BatchElevator.xlsx";

//2. 获取到它
File fileIn = new File(pathFrom );

//3. 写好后的模板存放的路径
String pathTo = ".." + File.separator + "doccenter" + File.separator + AppIdConstant.APPID + File.separator + "downLoadEquInfoTemp";

//4. 获取到(如果不存在,则创建此路径)
File fileCheck = new File(pathTo );
if (!fileCheck .exists()) {
    if (!fileCheck .mkdir()) {
        throw new RuntimeException("创建目录失败!");
    }
}

//5. 创建我们的目标模板
File fileOut = new File(pathTo + File.separator + "新取一个名字.xlsx");

//6. fileIn复制到fileOut  可用文件流FileStreams操作,但是效率低。这里我们使用FileChannel进行复制
copyFile(fileIn, fileOut);

//方法内容如下:
private static void nioTransferCopy(File source, File target) throws IOException {
    FileChannel in = new FileInputStream(source).getChannel();
    FileChannel out = new FileOutputStream(target).getChannel();
    in.transferTo(0, in.size(), out);
    in.close();
    out.close();
}

//7.获取XSSFWorkbook对象并输出
FileInputStream is = new FileInputStream(fileOut.getPath());
XSSFWorkbook wb = new XSSFWorkbook(is);
wb.write(new FileOutputStream(fileOut.getPath()));


注:实际上有以下方法可以构造对象,建议使用is构建,之前用path构造,其实需要调用close()方法将新建的xslx对象关闭,而关闭了该对象之后无法将文件输出,如果不关闭该对象又一直占用着这个地址导致输出流会报空指针错误,所以后来使用了XSSFWorkbook(java.io.InputStream is)这个构造方法,也建议使用该构造方法,调用该方法之后及时将输入流关闭,再输出文件的时候就不会报空指针错误了。
[图片]

三、如何用VBA做复选弹框

三、使用常用POI方法操作模板

1. 得到Excel常用对象
is = new FileInputStream(fileOut.getPath());
//得到Excel工作簿对象
XSSFWorkbook wb = new XSSFWorkbook(is);
//得到Excel工作表对象    
XSSFWorkbook sheet = wb.getSheetAt(0);   
//得到Excel工作表的行(下标从0开始)    
XSSFRow row = sheet.getRow(i);  
//得到Excel工作表指定行的单元格(下标从0开始) 
XSSFCell cell = row.getCell((short) j);
//得到单元格样式
cellStyle = cell.getCellStyle();  
2. 建立Excel常用对象
//创建Excel工作簿对象   
HSSFWorkbook wb = new HSSFWorkbook();

HSSFSheet sheet = wb.createSheet("new sheet");//创建Excel工作表对象     
HSSFRow row = sheet.createRow((short)0); //创建Excel工作表的行   
cellStyle = wb.createCellStyle();//创建单元格样式   
row.createCell((short)0).setCellStyle(cellStyle); //创建Excel工作表指定行的单元格   
row.createCell((short)0).setCellValue(1); //设置Excel工作表的值 

需要注意的是 getRow、getCell方法可能会获取不到未编辑过的单元格,报空指针,此时要用createRow、createCell方法!

在这里插入图片描述

3. 添加区域,合并单元格
//获取区域(下标从0开始)   
CellRangeAddress region= new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
// 到rowTo行columnTo的区域
sheet.addMergedRegion(region);      
//获得所有合并单元格的数量
int num = sheet.getNumMergedRegions();   

四、写入数据库数据

通过POI提供的基础方法,可以根据工作需要,写一个FilesUtil,或者创建一个FileProc实体类,提高工作效率。
举例:


/**
 * 处理.xlsx的sheet写入字典信息
 *
 * @param appId
 * @param dicName
 * @param sheet
 * @author fangwanchen
 * @date 2019/8/9 10:28
 */
public static void writeDicIntoXLSXSheet(String appId, String dicName, XSSFSheet sheet){
    JSONArray jsonArray = SDK.getDictAPI().queryValues(appId, dicName);
    if (jsonArray != null && jsonArray.size() > 0) {
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject obj = jsonArray.getJSONObject(i);
            String name = obj.getString("CNNAME");
            XSSFRow row = sheet.createRow(i);
            XSSFCell cell = row.createCell(0);
            cell.setCellValue(name);
        }
    }
}

//sheet1可以隐藏掉,sheet0下拉列表获取sheet1第一列的序列范围,ojbk
XSSFSheet sheetXMYT = wb.getSheetAt(1);
FilesUtil.writeDicIntoXLSXSheet(AppIdConstant.APPID, "MARKETSUBJECT.CODE.PURPOSE", sheetXMYT);
项目中想实现excel图表但POI不支持所以想到了这个方法。放上来抛砖引玉,感兴趣的欢迎大家交流 注:-------------------------------------------------------------------------- 其实现原理和利用JavaScript实现客户端绘图完全一样。后台代码将输入 写入特定区域,前端脚本在页面载入时执行脚本绘图。大家都是做B/S开发 的,这方面的只是不需要我多说了吧。 如果我们让一个HTML页面在载入时显示一个提示框用后台编程是不现实的 所以我们就动态生成一段JS: window.onload=function(){ ...... } 用Java输出图表的场景和这个一样,POI、JXL对操作Excel图表无能为力 但Excel支持脚本的,也有工作表载入事件,所以也可以用同样的原理实现 只不过这次客户端不再是浏览器而是Excel应用程序。 这样交代的应该比较明白了吧,请不要再留言抱怨没有Java代码了,因为 这根本跟java代码没多大关系,后台的代码所做的工作仅仅是写入必要的 数据,数据的解析和绘图操作是在VBA中完成的 ---2009-12-18 今天查找资料翻出来了这段代码,发现里边的类确实是空的,我说怎么总挨骂 呢,当时肯定打包的时候晕透了把另一个本该删除的类打包进去了。我无法 替换文件只能把java代码贴上来了,请自己修改模板文件的路径。 package com.test.poi; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; public class PoiChart { public static void main(String[] args){ try{ POIFSFileSystem fs=new POIFSFileSystem(new FileInputStream("E:/王建波_bak/我的练习/Module.xls")); HSSFWorkbook wb=new HSSFWorkbook(fs); HSSFSheet sheet=wb.getSheetAt(0); HSSFRow row; //写入表头 String[] aTblHeaders=new String[]{ "姓名","语文","数学","英语" }; row=sheet.createRow(0); for(int i=0,len=aTblHeaders.length;i<len;i++){ row.createCell((short)i).setCellValue(aTblHeaders[i]); } //向模板中写入数据 String[] aNames=new String[]{ "张飞","刘备","关羽","曹操","孙权","吕布" }; for(int i=0,nRowLen=aNames.length;i<nRowLen;i++){ row=sheet.createRow(i+1); row.createCell((short)0).setCellValue(aNames[i]); for(int j=1,nColLen=aTblHeaders.length;j<nColLen;j++){ row.createCell((short)j).setCellValue(Math.floor(Math.random()*100)); } } //输出文件 FileOutputStream fout=new FileOutputStream("d:/chart.xls"); wb.write(fout); fout.close(); }catch(Exception e){ e.printStackTrace(); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值