屁孩博客:使用POI操作Excel:Sheet拷贝

来源:互联网 发布:java 字节码 编辑:程序博客网 时间:2024/04/25 12:54
 

项目中很多模块需要将数据导出到Excel中,简单的如导出所有的用户信息到Excel,对于导出这种数据,可以通过POI/JXL直接生成Excel即可;当面临复杂格式的报表怎么办呢?下面这张图是项目中某张需要导出的Excel模版中部分截图,需求是根据查询条件生成N张同类型的这种单子到Excel中的不同Sheet中,后期要打印成纸质单据!需要明确有几个重点是:需要在A4纸中打印,所有打印出来的格式必须一样,可能后期这张表还会进行调整,必须满足其高扩展和变化性;

事实上我们依然可以通过程序将Excel写出来,事实上开始我确实也是这么做了,但是在做的过程中发现,要手写代码生成这种几十行的Excel实在是一个很大的工作量,尤其是对样式的控制更是繁琐;而且用程序生拼单元格生成Sheet不能正常打印到A4纸中,最后果断放弃,事实证明这个选择是正确的!

好吧,说了这么多总算进入正题,最后我选择了通过程序Copy整个Sheet的方式,采用通过这种实现方式,我只需要相关人员给我提供设置好模版,在批量生成的时候先通过Copy的方式生成新的Sheet,然后在向指定的Sheet中填写相关数据即可,而且当模版发生变化时只需调整Sheet中写值的代码即可!

重点是两个方法:copySheet和copyRow,主要代码如下:

 

package org.pihai.utils.excel.poi;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
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.hssf.util.Region;

/**
 * POI操作Excel
 * @since: 1.0
 * @version:1.0
 * @createTime:2011年07月21日 10:47:20
 * @updateTime:2011年07月21日 10:47:20
 * @author niejy  

 */
public class PoiExcelSheetCopy {
 
 /**
  * 根据源Sheet样式copy新Sheet
  * @param fromsheetname
  * @param newsheetname
  * @param targetFile
  */
 public void copySheet(String fromsheetname, String newsheetname,String targetFile) {
  HSSFWorkbook wb = null;
  try {
   FileInputStream fis = new FileInputStream(targetFile);
   wb = new HSSFWorkbook(fis);
   HSSFSheet fromsheet = wb.getSheet(fromsheetname);
   if (fromsheet != null && wb.getSheet(newsheetname) == null) {
    HSSFSheet newsheet = wb.createSheet(newsheetname);
    //设置打印参数
    newsheet.setMargin(HSSFSheet.TopMargin,fromsheet.getMargin(HSSFSheet.TopMargin));// 页边距(上)
    newsheet.setMargin(HSSFSheet.BottomMargin,fromsheet.getMargin(HSSFSheet.BottomMargin));// 页边距(下)
    newsheet.setMargin(HSSFSheet.LeftMargin,fromsheet.getMargin(HSSFSheet.LeftMargin) );// 页边距(左)
    newsheet.setMargin(HSSFSheet.RightMargin,fromsheet.getMargin(HSSFSheet.RightMargin));// 页边距(右
    
    HSSFPrintSetup ps = newsheet.getPrintSetup();
    ps.setLandscape(false); // 打印方向,true:横向,false:纵向(默认)
    ps.setVResolution((short)600);
    ps.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE); //纸张类型
    
    File file = new File(targetFile);
    if (file.exists() && (file.renameTo(file))) {
     copyRows(wb, fromsheet, newsheet, fromsheet.getFirstRowNum(), fromsheet.getLastRowNum());
     FileOutputStream fileOut = new FileOutputStream(targetFile);
     wb.write(fileOut);
     fileOut.flush();
     fileOut.close();
    } else {
     System.out.println("文件不存在或者正在使用,请确认...");
    }
   }
   fis.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 拷贝Excel行
  * @param wb
  * @param fromsheet
  * @param newsheet
  * @param firstrow
  * @param lastrow
  */
 public void copyRows(HSSFWorkbook wb, HSSFSheet fromsheet,HSSFSheet newsheet, int firstrow, int lastrow) {
  if ((firstrow == -1) || (lastrow == -1) || lastrow < firstrow) {
   return;
  }
  // 拷贝合并的单元格
  Region region = null;
  for (int i = 0; i < fromsheet.getNumMergedRegions(); i++) {
   region = fromsheet.getMergedRegionAt(i);
   if ((region.getRowFrom() >= firstrow)&& (region.getRowTo() <= lastrow)) {
    newsheet.addMergedRegion(region);
   }
  }

  HSSFRow fromRow = null;
  HSSFRow newRow = null;
  HSSFCell newCell = null;
  HSSFCell fromCell = null;
  // 设置列宽
  for (int i = firstrow; i <= lastrow; i++) {
   fromRow = fromsheet.getRow(i);
   if (fromRow != null) {
    for (int j = fromRow.getLastCellNum(); j >= fromRow.getFirstCellNum(); j--) {
     int colnum = fromsheet.getColumnWidth((short) j);
     if (colnum > 100) {
      newsheet.setColumnWidth((short) j, (short) colnum);
     }
     if (colnum == 0) {
      newsheet.setColumnHidden((short) j, true);
     } else {
      newsheet.setColumnHidden((short) j, false);
     }
    }
    break;
   }
  }
  // 拷贝行并填充数据
  for (int i = 0; i <= lastrow; i++) {
   fromRow = fromsheet.getRow(i);
   if (fromRow == null) {
    continue;
   }
   newRow = newsheet.createRow(i - firstrow);
   newRow.setHeight(fromRow.getHeight());
   for (int j = fromRow.getFirstCellNum(); j < fromRow.getPhysicalNumberOfCells(); j++) {
    fromCell = fromRow.getCell((short) j);
    if (fromCell == null) {
     continue;
    }
    newCell = newRow.createCell((short) j);
    newCell.setCellStyle(fromCell.getCellStyle());
    int cType = fromCell.getCellType();
    newCell.setCellType(cType);
    switch (cType) {
    case HSSFCell.CELL_TYPE_STRING:
     newCell.setCellValue(fromCell.getRichStringCellValue());
     break;
    case HSSFCell.CELL_TYPE_NUMERIC:
     newCell.setCellValue(fromCell.getNumericCellValue());
     break;
    case HSSFCell.CELL_TYPE_FORMULA:
     newCell.setCellFormula(fromCell.getCellFormula());
     break;
    case HSSFCell.CELL_TYPE_BOOLEAN:
     newCell.setCellValue(fromCell.getBooleanCellValue());
     break;
    case HSSFCell.CELL_TYPE_ERROR:
     newCell.setCellValue(fromCell.getErrorCellValue());
     break;
    default:
     newCell.setCellValue(fromCell.getRichStringCellValue());
     break;
    }
   }
  }
 }
 
 public static void main(String[] args) {
  PoiExcelSheetCopy ew = new PoiExcelSheetCopy();
  ew.copySheet("template", "test2", "d:/template.xls");
 }
}

这段代码依赖POI的jar包,上面的代码可能还是不是很简洁,有待抽空进行优化!重点是先把这种解决方案分享给大家!

 

更多信息请看这里:屁孩博客

原创粉丝点击