POI合并单元格,冻结窗口例子

时间:2022-12-14 20:33:40

/**
 * 生成多种格式的Excel
 * */
package multiStruct;

import java.io.FileOutputStream;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
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;

public class POI_MultiStruct
{
 /**
  * @param args
  */
 public static void main(String[] args)
 {
  try
  {
   //创建一个空白的WorkBook
   HSSFWorkbook wb = new HSSFWorkbook();
   //基于上面的WorkBook创建属于此WorkBook的Sheet
   HSSFSheet st = wb.createSheet();
   wb.setSheetName(0,"测试页",HSSFWorkbook.ENCODING_UTF_16);
   HSSFCellStyle normalStyle = createNormalStyle(wb);
   // 合并单元格A1-C1,填入内容的时候添到第一个格子里就可以
   // 但是注意一点:单元格合并後设置边框只在原第一个上有效,
   // 如果想应用的合并後的整体,则需要一个个的Create出单元格并应用样式
   st.addMergedRegion(new Region(0, (short) 0, 0, (short) 2));//跨一行三列
   HSSFRow row = st.createRow(0);
   HSSFCell cell = row.createCell((short) 0);
   cell.setEncoding(HSSFCell.ENCODING_UTF_16);
   cell.setCellValue("业务一览表");
   //cell.setCellValue("Business list");//业务一览表
   cell.setCellStyle(normalStyle);
   row.createCell((short) 1).setCellStyle(normalStyle);
   row.createCell((short) 2).setCellStyle(normalStyle);
   // 设置列头,当然也可以一个一个格子的写,用循环感觉有些取巧而已
   // 同样,需要单独给每个单元格应用样式对象
   String[] seasonName = { "第一季度", "第二季度", "第三季度", "第四季度" };
   //String[] seasonName = { "The first quarter", "The second quarter", "The third quarter", "The fourth quarter" };
   for (short i = 3; i < 7; i++)
   {
    cell = row.createCell(i);
    cell.setEncoding(HSSFCell.ENCODING_UTF_16);
    cell.setCellValue(seasonName[i - 3]);
    cell.setCellStyle(normalStyle);
   }
   // 这个是竖排文字的实现
   // 目前POI没找到(或许没提供,或许我无知)让文字竖排的方法,
   // HSSFCellStyle.setRotation()方法是设置旋转角度的,和竖排不太一样
   st.addMergedRegion(new Region(1, (short) 0, 6, (short) 0));
   row = st.createRow(1);
   cell = row.createCell((short) 0);
   cell.setEncoding(HSSFCell.ENCODING_UTF_16);
   cell.setCellValue("地/n区/n代/n理/n");
   //cell.setCellValue("Area/nLocation/nProxy/nEr/n");
   cell.setCellStyle(normalStyle);
   for (int i = 2; i < 7; i++)
   {
    st.createRow(i).createCell((short) 0).setCellStyle(normalStyle);
   }
   // 属于地区的二级分类,竖向合并相邻的两个单元格,其他同上
   String[] shopName = { "连锁店A", "连锁店B", "连锁店C" };
   //String[] shopName = { "chain store A", "chain store B", "chain store C" };
   for (int i = 1; i < 6; i = i + 2)
   {
    row = st.createRow(i);
    cell = row.createCell((short) 1);
    cell.setEncoding(HSSFCell.ENCODING_UTF_16);
    cell.setCellValue(shopName[(i - 1) / 2]);
    cell.setCellStyle(normalStyle);
    st.createRow(i + 1).createCell((short) 1).setCellStyle(normalStyle);
    st.addMergedRegion(new Region(i, (short) 1, i + 1, (short) 1));
   }
   // 属于连锁店的下一级,基本也是创建出来然后赋值+应用样式
   for (int i = 1; i < 7; i = i + 2)
   {
    cell = st.getRow(i).createCell((short) 2);
    cell.setEncoding(HSSFCell.ENCODING_UTF_16);
    cell.setCellValue("收入");
    //cell.setCellValue("income");
    cell.setCellStyle(normalStyle);
    cell = st.getRow(i + 1).createCell((short) 2);
    cell.setEncoding(HSSFCell.ENCODING_UTF_16);
    cell.setCellValue("支出");
    //cell.setCellValue("expenses");
    cell.setCellStyle(normalStyle);
    
   }
   // 数据部分,直接Create然后应用样式,有数据的话这个地方就打数据好了
   for (int i = 1; i < 7; i++)
   {
    for (short j = 3; j < 7; j++)
    {
     cell = st.createRow(i).createCell(j);
     cell.setCellStyle(normalStyle);
     cell.setCellValue(i*j);
    }
   }
   // 冻结Excel的窗口,边界为数据部分的边界
   st.createFreezePane(3, 1);
   // 按照连锁店级别分组
   for (int i = 1; i < 7; i = i + 2)
   {
    st.groupRow(i, i);
   }
   // 按照地区分组
   st.groupRow(1, 5);
   //--
   FileOutputStream writeFile = new FileOutputStream("D://POI_Export//multiStructExcel.xls");
   //输出
   wb.write(writeFile);
   writeFile.close();
  }
  catch(Exception ex)
  {
   ex.printStackTrace();
  }
 }
 
 public static HSSFCellStyle createNormalStyle(HSSFWorkbook wb)
 {
  HSSFCellStyle normalStyle = wb.createCellStyle();
  // 这里首先创建一个单元格样式对象,设置了四周的边框以及字体可以换行
  // 其中的字体换行是用来竖向显示其中的一个单元格的
  // 更好的一点儿做法是再做一个单独的单元格样式对象
  // 要不然在处理自动列宽的时候可能会有点儿小问题
  normalStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
  normalStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
  normalStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
  normalStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
  normalStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
  normalStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  normalStyle.setWrapText(true);
  return normalStyle;
 }
}