• 一个复杂的poi处理 合并单元格及其样式对齐问题


    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.text.DateFormat;
    import java.text.DecimalFormat;
    import java.text.ParseException;
    import java. text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    
    import javax.inject.Inject;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.hssf.util.HSSFColor;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.DataFormat;
    import org.apache.poi.ss.usermodel.Font;
    import org.apache.poi.ss.usermodel.PrintSetup;
    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.ss.util.CellUtil;
    import org.springframework.beans.factory.config.ConfigurableBeanFactory;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.tshn.hydrology.base.BaseUtil;
    import com.tshn.hydrology.base.Consts;
    import com.tshn.hydrology.entity.system.Organization;
    import com.tshn.hydrology.service.modules.StPptnRService;
    
    
    @Controller
    @RequestMapping("stPptnR")
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public class StPptnRDetailsExcelExport {
         @Inject
         private StPptnRService stPptnRservice;
         private  final int ZONE_NAME_CELL_STYLE = 1;
         private  final int COMMON_CEELL_STYLE = 2;
         private  final int AVG_RAIN_CELL_STYLE = 3;
         private  final int NUMBERIC_CELL_STYLE = 4;
         private  String decimalFormatPattern = "0.0"; //
         private  String rainDetailExcelName = "雨晴表year.第xx期.xls"; //excel名称
         private  DateFormat  dateFormat = new SimpleDateFormat("yyyy-MM-dd HH");
         private  DateFormat  chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时");
         private  DateFormat  chineseDateFormatNoYear = new SimpleDateFormat("MM月dd日HH时");
         private  Calendar cal = Calendar.getInstance();
         private  int[] queryDatePosition = {3,5}; //excel模版放置查询时间段的位置(3行5列)
         private String templatePath = BaseUtil.getDefultAttPrefixPath()+Consts.STANDARD_REPORT_TEMPLATE; //excel模版位置
         private int rowZoneNum =3; //每行存放的县区个数
         private String[][] allAreaRainStatistics =
                 new String[][]{{"平均","parentAvg","AVERAGE"},{"最大","parentMax","MAX"},{"最小","parentMin","MIN"}}; //全区统计
         
         @RequestMapping("exportRegularRainDetailsExcel")
          public void  exportRegularRainDetailsExcel(HttpServletRequest request,HttpServletResponse response,Model model){
            String startTime = request.getParameter("startTime"); //开始查询时间
            String endTime = request.getParameter("endTime"); //结束查询时间
            try {
                Date startDate = dateFormat.parse(startTime);
                Date endDate = dateFormat.parse(endTime);
                rainDetailExcelName = rainDetailExcelName.replaceAll("year", getQueryYear(startDate)); //根据查询日期重新设置excel表格名称
                String queryDateSection = chineseDateFormat.format(startDate)+"~"+chineseDateFormatNoYear.format(endDate); //设置查询时间段
                stPptnRservice.getStPptnRDetails(model,request); 
                Map<String, Object>  data = model.asMap(); //降雨量信息
                Workbook excelBook = getWrittenExcelbook(queryDateSection,data); //写excel
                
                response.setContentType("application/x-msdownload"); // 通知客户文件的MIME类型:
                 try {
                    response.setHeader("Content-disposition", "attachment;filename="+new String(rainDetailExcelName.getBytes(),"ISO-8859-1"));
                    excelBook.write(response.getOutputStream());
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
          }
         
         /**
          * 计算起始查询日期的年份
          * @param startDate 
          * @return
          */
         private String getQueryYear(Date startDate){
            cal.setTime(startDate);
            return String.valueOf(cal.get(Calendar.YEAR));
         }
         
         
     
         
         
         @SuppressWarnings("unchecked")
        private Workbook getWrittenExcelbook(String queryDateSection,Map<String, Object>  data){
             int startWirteRowNum = 5;//开始行数
             StringBuffer calculateArea = new  StringBuffer();
             Workbook workbook = null;
            try {
                workbook = new HSSFWorkbook(new FileInputStream(templatePath));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
             Sheet sheet = workbook.getSheetAt(0);
             sheet.setColumnWidth(1, 2180);
             sheet.setColumnWidth(4, 2180);
             sheet.setColumnWidth(7, 2180);
             //在queryDatePosition 指定的位置写入查询时间
             sheet.getRow(queryDatePosition[0]).getCell(queryDatePosition[1]).setCellValue(queryDateSection);
             
             List<Map<String,Object>> stpps  = (List<Map<String,Object>>)data.get("stpps");
             
             int[] currentRowNums = new int[rowZoneNum];  
             for(int m=0;m<currentRowNums.length;m++){
                 currentRowNums[m]=startWirteRowNum;
             }
             for(int i=0;i<stpps.size();i++){
                   Map<String,Object> sttp  = stpps.get(i);
                   String mainOrgName = String.valueOf(sttp.get("orgName"));
                   
                   List<Organization> childOrgs = (List<Organization>)sttp.get("child");
                   int rowNum = childOrgs.size()+1; //各乡镇降雨量+县区平均降雨量
                   int columnZoneIndex = i%rowZoneNum;
                   int startRowNum = currentRowNums[columnZoneIndex];
                   int endRowNum = currentRowNums[columnZoneIndex]+rowNum-1;
                   int startAndEndColumnNum = i%rowZoneNum*rowZoneNum;
                
                   //合并县区名称单元格
                   CellRangeAddress cellRangeAddress = new CellRangeAddress(startRowNum, endRowNum, startAndEndColumnNum, startAndEndColumnNum);
                   sheet.addMergedRegion(cellRangeAddress);
               
                   
                   Row currentRow = null;
                   Cell startCalCell = null;
                   Cell endCalCell = null;
                   for(int j=0;j<rowNum;j++){
               
                       if( sheet.getRow(currentRowNums[columnZoneIndex]) == null){
                           currentRow =  sheet.createRow(startWirteRowNum++);
                           currentRowNums[columnZoneIndex] = startWirteRowNum;
                       }else{
                           currentRow = sheet.getRow(currentRowNums[i%rowZoneNum]);
                           currentRowNums[columnZoneIndex] = currentRowNums[columnZoneIndex]+1;
                       }
                       
                       Cell orgNameCell = currentRow.createCell(startAndEndColumnNum+1);//存放站名单元格
                      
                       Cell rainCell = currentRow.createCell(startAndEndColumnNum+2);//存放降雨雨量
                       rainCell.setCellType(Cell.CELL_TYPE_NUMERIC);
                    rainCell.setCellStyle(this.getCustomedCellStyle(workbook, NUMBERIC_CELL_STYLE));
                      if(rowNum-1>j){
                           Organization org =  childOrgs.get(j);
                           orgNameCell.setCellStyle(this.getCustomedCellStyle(workbook, COMMON_CEELL_STYLE));
                           orgNameCell.setCellValue(org.getOrganizationName()); //设置站名
                           if(j == 0){
                              if(!mainOrgName.equals("开发区")){    
                                  orgNameCell.setCellValue("城区");
                              }   
                               startCalCell = rainCell;
                           }else if(j==rowNum-2){
                               endCalCell = rainCell;
                           }
                           rainCell.setCellValue(org.getAvgOfStpptnR()); //设置降雨量
                      }else{//设置县区平均降雨量
                          orgNameCell.setCellStyle(this.getCustomedCellStyle(workbook, AVG_RAIN_CELL_STYLE));
                          orgNameCell.setCellValue(mainOrgName.substring(mainOrgName.length()-1)+"平均");
                          rainCell.setCellValue(Double.parseDouble(String.valueOf(sttp.get("avg"))));
                          String excelArea = this.tranlateExcelArea(startCalCell, endCalCell); //获取excel区域
                          calculateArea.append(excelArea).append(",");
                          this.setFormula(rainCell,"AVERAGE",excelArea); //给平均雨量单元格设置公式
                      }
                     
                   }
                   
                for (int m = cellRangeAddress.getFirstRow(); m <=  cellRangeAddress.getLastRow(); m ++) {//设置表头单元格样式
                    CellUtil.getCell(sheet.getRow(m), startAndEndColumnNum).setCellStyle(this.getCustomedCellStyle(workbook, ZONE_NAME_CELL_STYLE));
                }
                 Cell areaCell = CellUtil.getCell(sheet.getRow( cellRangeAddress.getFirstRow()), startAndEndColumnNum);
                 
                 areaCell.setCellValue(getStringWithEnter(mainOrgName));
                 
                   
                 
             }
             
             int minArrayValueIndex = 2;
             int currentRowNum = currentRowNums[minArrayValueIndex] ;
             int lastRowColumnIndex = minArrayValueIndex*3 ;
             //合并竖行单元格
             CellRangeAddress cellRangeAddress = new CellRangeAddress(currentRowNum, currentRowNum+2, lastRowColumnIndex, lastRowColumnIndex);
             sheet.addMergedRegion(cellRangeAddress);
             
             calculateArea.deleteCharAt(calculateArea.length()-1);//删除最后一个逗号
             for(int k=0;k<3;k++){
                 if(sheet.getRow(k+currentRowNum)==null){
                     sheet.createRow(k+currentRowNum);
                 }
                 Row tempRow = sheet.getRow(k+currentRowNum);
                 Cell  dataNameCell  =  tempRow.createCell(lastRowColumnIndex+1); //数据名称
                 dataNameCell.setCellStyle(this.getCustomedCellStyle(workbook, ZONE_NAME_CELL_STYLE));
                 dataNameCell.setCellValue(allAreaRainStatistics[k][0]);
                 Cell  dataContentCell  =  tempRow.createCell(lastRowColumnIndex+2); //数据内容
                 dataContentCell.setCellType(Cell.CELL_TYPE_NUMERIC);//设置单元格类型
                 dataContentCell.setCellStyle(this.getCustomedCellStyle(workbook,NUMBERIC_CELL_STYLE));
                 dataContentCell.setCellValue(Double.parseDouble(String.valueOf(data.get(allAreaRainStatistics[k][1]))));
                 this.setFormula(dataContentCell, allAreaRainStatistics[k][2], calculateArea.toString());
             } 
             currentRowNums[minArrayValueIndex] =   currentRowNums[minArrayValueIndex] + 3;
             for (int m = cellRangeAddress.getFirstRow(); m <=  cellRangeAddress.getLastRow(); m ++) {//设置表头单元格样式
                 CellUtil.getCell(sheet.getRow(m), lastRowColumnIndex).setCellStyle(this.getCustomedCellStyle(workbook, ZONE_NAME_CELL_STYLE));
             }
             Cell areaCell = CellUtil.getCell(sheet.getRow( cellRangeAddress.getFirstRow()), lastRowColumnIndex);
             
             areaCell.setCellValue("全市\r\n统计");
             
             //动态补齐单元格
             int maxArrayValueIndex =  getMaxArrayValueIndex(currentRowNums);
             int maxArrayValue = currentRowNums[maxArrayValueIndex];
             for(int i=0;i<currentRowNums.length;i++){
                 if(i!=maxArrayValueIndex && maxArrayValue>currentRowNums[i]){ //如果该列单元格的行数 小于 最多行的单元格,那么动态补齐该列单元格
                      int startMergedRegionRow = currentRowNums[i]-1; //开始行数
                      int endMergedRegionRow = maxArrayValue-1; //结束行数
                      for(int m=0;m<3;m++){
                          CellRangeAddress cellRange =   new CellRangeAddress(startMergedRegionRow, endMergedRegionRow, i*rowZoneNum+m,  i*rowZoneNum+m);
                          sheet.addMergedRegion(cellRange);
                          for (int x = startMergedRegionRow; x <= endMergedRegionRow; x++) {
                              CellUtil.getCell(sheet.getRow(x),  i*rowZoneNum+m).setCellStyle(
                                      getCustomedCellStyle(workbook,i*rowZoneNum+m==0 ? ZONE_NAME_CELL_STYLE : (i*rowZoneNum+m==1 ? AVG_RAIN_CELL_STYLE : NUMBERIC_CELL_STYLE ))
                                );
                          }
                      }  
                      
                      
                 }
             }
             
             /*--打印设置--*/
            PrintSetup   printSetUp = sheet.getPrintSetup();
            sheet.setAutobreaks(true);
            printSetUp.setFitHeight((short)1); //一页打印
            printSetUp.setPaperSize(PrintSetup.A4_PAPERSIZE);//设置
            sheet.setHorizontallyCenter(true);//设置打印页面为水平居中  
            sheet.setVerticallyCenter(true);//设置打印页面为垂直居中  
             
             return workbook;
             
         }
         
         
         /**
          * 根据开始单元格和结束单元格,获取两个单元格之间的Excel区域
          * @param startCalCell
          * @param endCalCell
          * @return
          */
         private String tranlateExcelArea(Cell startCalCell,Cell endCalCell){
             int startCellColumnIndex = startCalCell.getColumnIndex();//获取单元格列索引
             int startCellRowIndex = startCalCell.getRowIndex(); //获取单元格行索引
             
             int endCellColumnIndex = endCalCell.getColumnIndex();//获取单元格列索引
             int endCellRowIndex = endCalCell.getRowIndex(); //获取单元格行索引
             
             String startCellStr = BaseUtil.transformArabNoToEnglishNo(startCellColumnIndex, true)
                                     + (startCellRowIndex+1);
             String endCellStr = BaseUtil.transformArabNoToEnglishNo(endCellColumnIndex, true)
                     + (endCellRowIndex+1);
             return startCellStr+":"+endCellStr; 
         }
         
         private void setFormula(Cell cell,String formulaName,String calculateArea){
             cell.setCellFormula(formulaName+"("+calculateArea+")");
         }
         
         
         /**
          * 在每个字符后追加回车符
          * @param inputStr
          * @return
          */
         private String getStringWithEnter(String inputStr){
              String[] mainOrgNames = inputStr.split("");
              String finalMainOrgName = "";//实现县区竖排效果
              for(int x=0;x<mainOrgNames.length;x++ ){ 
                  finalMainOrgName += mainOrgNames[x] +"\r\n";
              }
              return finalMainOrgName;
         }
         
         private CellStyle getCustomedCellStyle(Workbook workbook,int cellStyleType){
             CellStyle newCellStyle =   workbook.createCellStyle();
             Font font = workbook.createFont();
             font.setFontName("仿宋_GB2312");
             
             if(cellStyleType == ZONE_NAME_CELL_STYLE){
                 font.setFontName("黑体");
                 font.setFontHeightInPoints((short) 12);
                 font.setBoldweight(Font.BOLDWEIGHT_BOLD);
                 newCellStyle.setFont(font);
                 newCellStyle.setWrapText(true);
                 //newCellStyle.setRotation((short)-90); //字体旋转90度
             }else if(cellStyleType==AVG_RAIN_CELL_STYLE){
                 font.setFontHeightInPoints((short) 12);
                 font.setBoldweight(Font.BOLDWEIGHT_BOLD);
                 font.setColor(HSSFColor.ROYAL_BLUE.index);
                 newCellStyle.setFont(font);
                 newCellStyle.setFillBackgroundColor(HSSFColor.GREY_80_PERCENT.index);
             }else if(cellStyleType  == NUMBERIC_CELL_STYLE){
                DataFormat format =  workbook.createDataFormat();
                newCellStyle.setDataFormat(format.getFormat(decimalFormatPattern));
             }else{
                 font.setFontHeightInPoints((short) 12);
                 font.setBoldweight(Font.BOLDWEIGHT_NORMAL);
                 newCellStyle.setFont(font);
             }
             
             newCellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //垂直居中
             newCellStyle.setAlignment(CellStyle.ALIGN_CENTER); //水平居中
             this.setBorder(newCellStyle, CellStyle.BORDER_THIN);   //设置单元格边框
             
             return newCellStyle;
         }
         
         /**
          * 获取数组中最小元素对应的数组索引
          * @param array
          * @return
          */
         private int getMaxArrayValueIndex(int[] array){
             int maxValue = array[0];
             int maxValueIndex = 0;
             for(int i=0;i<array.length;i++){
                 if(maxValue<array[i]){
                     maxValue = array[i];
                     maxValueIndex = i;
                 }
             }
             
             return maxValueIndex;
             
         }
         
         /**
             * 设置单元格边框宽度
             * @param cellStyle
             * @param borderWidth
             */
            private void setBorder(CellStyle cellStyle,short borderWidth){
                cellStyle.setBorderTop(borderWidth);
                cellStyle.setBorderBottom(borderWidth);
                cellStyle.setBorderLeft(borderWidth);
                cellStyle.setBorderRight(borderWidth);
            }
            
             
         
            
             
    }
  • 相关阅读:
    linux的文件权限分析
    Bash 文件夹操作
    bash shell 文本文件操作
    Vim文字编辑
    Windows环境Vim编辑器如何执行Ruby代码
    JavaWeb-Servlet
    app遮罩层--网赚
    flex布局 居中
    实现绝对定位元素水平垂直居中的两种方法
    CSS背景图怎么自适应全屏(手机或者电脑)
  • 原文地址:https://www.cnblogs.com/lcuzhanglei/p/2875288.html
Copyright © 2020-2023  润新知