上次的项目是用日本的seasar2框架的开发
这里的excel是个模板,里面有代码,出力excel 的时候读取模板然后出力public interface IPsape312Fpao {

HSSFWorkbook outputExcel(ExcelDto dto);
}这里是java fpao代码
ExcelDto dto 我想大家都应该知道是存数据的地方
${data.ssnNo!}
${data.kozaNameKanji!}
${data.ssnName!}
${data.syozoku!}
${data.organizationName!}
${data.kmkName!} 上面的这些代码是在excel的cell中写的
data后面点出来的属性就是传入的dto中的属性这是我第一次接触在excel 中写代码的程序
我现在想和大家探讨下,java怎么操纵excel中的代码,实现数据传输
我那项目封装的很厉害 虽然是开源但是我没有找到代码
我想自己写一个这样的类 请教下大家
希望大家给给意见 开拓下思路
当然要是写过这样的代码的人发点代码出来更好啦
谢谢大家了

解决方案 »

  1.   

    我米用过楼主说的那个框架,但是基本上对excel导入导出都是一样的思想吧。
    前些天自己写了一个导入的代码java滴,你参看下好了: /**
        * 导入函数
        */
        public ActionForward importInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                HttpServletResponse response) throws Exception
        {
         String teamName = null;
         String teamerName = null;
         String re = null;
         String excelName = null;
         excelName = request.getParameter("excelName");
         //定义动态form,并取得要导入的文件
         //DynaActionForm dForm = (DynaActionForm )form;
         //FormFile formFile = (FormFile)dForm.get("excelFile");
         InputStream in = null;
         try{
         /*if(formFile == null){
         throw new ServiceException("读取页面上传入的文件失败!");
         }*/
         //用HSSFWorkbook来定义导入的文件类型是excel类型的
         //HSSFWorkbook wb = new HSSFWorkbook(formFile.getInputStream());
         //取得第一个sheet1来读取数据
         //wb.getSheet("sheet1");
         //String sheetName = formFile.("sheetName");
         //in = formFile.getInputStream();
         in = new FileInputStream(excelName);
         if (in == null) {
    throw new ServiceException("读入文件流失败");
    }    }catch (FileNotFoundException  e) {
          e.printStackTrace();
    in.close();
    throw new ServiceException("文件不存在,或路径错误");
    }catch (IOException e) {
    e.printStackTrace();
    in.close();
    throw new ServiceException("文件的格式不对,请选择正确的文件。格式应该已.XLS");
    }
    //定义一个存放数据的载体
    @SuppressWarnings("unused")
    List<ComQueryManagerVO> infoList = new ArrayList<ComQueryManagerVO>();
    infoList = readXLSDocument(in);

    if(infoList.size()>0){
    for(int i = 0,listLen = infoList.size(); i<listLen; i++){
    ComQueryManagerVO reVo = infoList.get(i);
        teamName = reVo.getTeamName();
        teamerName = reVo.getTeamerName();
        re = reVo.getRe();
    try{ 
     comQueryManagerBO.addInfo(teamName,teamerName,re);
     request.setAttribute("MESSAGE", "添加信息成功");
         }catch (Exception e) {
               // TODO: handle exception
         e.printStackTrace();
    }
    }
    }
    return mapping.findForward("List");
        }
        
        /**
         * 读取文件流
         */
        private  List<ComQueryManagerVO> readXLSDocument( InputStream in)throws FileNotFoundException, IOException, Exception{
        
         HSSFWorkbook workBook = new HSSFWorkbook(in); // 包装流
    HSSFSheet sheet = workBook.getSheetAt(0); // EXCEL文件里具体的表的编号,从0开始
    //读取sheet页的信息
    List<ComQueryManagerVO> reList = readXLSDocumentInfo(sheet);
        
    return reList;
        
        }
        
        /**
         * 读取导入sheet页上的信息
         */
        private  List<ComQueryManagerVO> readXLSDocumentInfo(HSSFSheet sheet)throws FileNotFoundException, IOException, Exception{
         //先定义一个要返回最终的结果的list
         List<ComQueryManagerVO> reInfoList = new ArrayList<ComQueryManagerVO>();
         //分别得到sheet页里第一个和最后一行的行号
         int firstNum = sheet.getFirstRowNum();
         int lastNum = sheet.getLastRowNum();
         //在定义一个单元格出错时候的错误信息存储
         String errorCell = "";
         String errorCellLen = "";
         String errorCellConp = "";
         for(int i = firstNum+1; i <= lastNum; i++ ){
         //先是跳过了第一行的标题
         HSSFRow row = sheet.getRow(i);
         //这里可以按照规定写了,就是如果出现空行,可以跳过这空行,或者按需要加别的判断
         if(row == null){
         continue;
         }
         /*得到一行后,就要判断这行的单元格的数据是否正确了。
           此处的思想是,先判断单元格内数据的正确性,然后在进行读取存入数据
         */
         HSSFCell cell = row.getCell(0);
         if(cell == null || cell.toString().trim().length()<1){
         System.out.println("此单元格的数据不能为空"+errorCell);
         errorCell += ("("+(i)+",B)"+"此单元格的数据不能为空");
         }else{
         String c = cell.toString().trim();
         if(c.length()>20){
         System.out.println("此单元格的长度不能大于20"+errorCellLen);
         errorCellLen += "此单元格的长度不能大于20";
         }
         }
        
         cell = row.getCell(1);
         if(cell == null || cell.toString().trim().length()<1){
         System.out.println("此单元格的数据不能为空"+errorCell);
         errorCell += ("("+(i)+",c)"+"此单元格的数据不能为空")
         }else{
         String c = cell.toString().trim();
         if(c.length()>20){
         System.out.println("此单元格的长度不能大于20"+errorCellLen);
         errorCellLen += "此单元格的长度不能大于20";
         }
         }
         }
         if(errorCell.length()>1){
        String errorInfo = "单元格读取错误: 坐标"+errorCell;
         throw new ServiceException("errorCell错误信息 "+errorInfo);     }
         if(errorCellLen.length()>1){
         String errorInfo = "单元格读取错误: 坐标"+errorCellLen;
        throw new ServiceException("errorCellLen错误信息 "+errorInfo);     }
         /*判断完基本的容错信息后,就开始读取存储导入的信息了*/
         String teamName = "";
         String teamerName = "";
         String re = "";
         String teamNameTemp = "";
        
         for (int i = firstNum + 1; i <= lastNum; i++) {
    // 跳过第一行的标题
    HSSFRow row = sheet.getRow(i);
    // 如果出现空行,则跳过 ,直接读取下一行
    if (row == null){
    continue;
    }
    HSSFCell cell = null;
    HSSFCell tempCell = null;
    ComQueryManagerVO tempVo = new ComQueryManagerVO(); cell = row.getCell(1);
    teamerName = cell.toString().trim();
    tempVo.setTeamerName(teamerName);

    cell = row.getCell(2);
    re = cell.toString().trim();
    tempVo.setRe(re);

    cell = row.getCell(0);
    teamName = cell.toString().trim();

    //判断球队的名字不能相同
    for(int j = i+1; j <= lastNum; j++){
    HSSFRow rowConp = sheet.getRow(j);
    if (rowConp == null){
    continue;
    }
    tempCell = rowConp.getCell(0);
    teamNameTemp = tempCell.toString().trim();
    if(teamNameTemp.equals(teamName)){
             errorCellConp += ("(" + (i) + ",A)")
    + ("(" + (j + 1) + ",A)"); }

    }
    if (errorCellConp.length() > 1) {

    System.out.println("该单元格的字段不容许重复"+errorCellConp);
    errorCellConp = "单元格读数据错误:坐标" + errorCellConp;
    throw new ServiceException("该单元格的字段不容许重复");
    }
    tempVo.setTeamName(teamName);
    reInfoList.add(tempVo);
         }
         return reInfoList;
        }ps:这里粘出来的代码格式真难看,影响我的形象呢,o(∩_∩)o..
      

  2.   

    没关系 我就认为你很漂亮就OK了
    谢谢美女 我研究下你这程序在exce中写代码了?
    我那里的第二行代码是在excel写的
      

  3.   

    读取写入excel 有很多jar都可以实现
    js也可以
    但是我遇到这个封装的seasar中
    出力excel的时候太帅气了
    自己在excel中定义自己想要的模板
    在模板中把你要输入的数据用导入的dto传进去写入代码
    当然 做循环也是在excel中写的
    但是我觉得是 java poi操纵的excel
    怎么实现的不清楚  
    希望大家一起说说看法
      

  4.   


    lz呀,我用的就是poi写的啊,那些代码是要导入包的:
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;你说的框架我没用过啊,所以我写的就是我用过的方法。还有,我已经往excel里写数据了,你说的
    ${data.ssnNo!}                                            
    ${data.kozaNameKanji!}                                            
    ${data.ssnName!}                                            
    ${data.syozoku!}                                            
    ${data.organizationName!}                                            
    ${data.kmkName!}  这个变量,完全可以在指定的cell里写入就可以了。
      

  5.   

    ssnNo,kozaNameKanji,ssnName都是传入的DTO的属性字段
    你就在EXCEL这样写就可以取到DTO的所有属性?
    我那项目里还有 #foreach 这样的代码
    在EXCEL中做循环
      

  6.   

    lz,百度一下,所有excel问题都解决
      

  7.   


    晕,你还是一直在你的环境里
    我都说了,我的这个是poi写的,你的框架我没用过,所以我不能用你的框架和方法去写。
    我说的这个是给你举例而已,就是说你要自己得到这个变量,然后放到对应的excle的cell里,如果这是你的需求的话。
      

  8.   

    我认为在excel写代码不是框架完成的
    就是一个封装的jar完成
    jar不就是一个自己写好的很多类吗
    我现在想自己写
    希望给意见
    谢谢你的poi
      

  9.   

    到apache 上去查poi的资料不就什么都有了
      

  10.   

    站着说话腰不疼吗?我强调下,这个技术不是那么简单的
    主要是怎么实现EXCEL中的程序代码