记录:
//先设置类型再设值,否则会导致数值变化
//样式之间会互相覆盖
maven依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
代码1.0,取消合并单元格方法有点问题(回头整理)
import com.ucaret.statistics.dao.DetailReportMapper;
import com.ucaret.statistics.query.PgQuery;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ucaret.statistics.service.DetailReportService;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service(value="detailReportService")
public class DetailReportServiceImpl implements DetailReportService {
@Autowired
private DetailReportMapper detailReportMapper;
@Override
public void downFile() throws Exception{
String fileName = "E:/tem/明细账.xlsx"; // 修改的.xlsx文件
String SheetName = "Sheet";
int cpage = 1;//默认第一页
int pagesize = 5000;//默认5000条
int qingli = pagesize;
XSSFWorkbook xwb = new XSSFWorkbook(new FileInputStream(fileName));
XSSFSheet xSheet = xwb.getSheetAt(0);
for(int k = 4;k <= xSheet.getLastRowNum();k++){
//清理多余数据
if(xSheet.getRow(k) != null){
xSheet.removeRow(xSheet.getRow(k));
}
}
XSSFCellStyle cellStyle = xwb.createCellStyle();
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setAlignment(HorizontalAlignment.CENTER); //居中
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //垂直
List<Map<String,Object>> roomlist = detailReportMapper.excelFindStoried();
int biao = 0;
for (int i = 0;i < roomlist.size();i++){
int rowget4 = 4+biao;
if(i==0){
qingli+=rowget4;
}
Map<String,Object> pm = roomlist.get(i);
XSSFRow row = xSheet.getRow(rowget4)==null ? xSheet.createRow(rowget4) : xSheet.getRow(rowget4);//获取一行或创建一行
row.createCell(0).setCellValue(pm.get("storied_no").toString());
row.createCell(1).setCellValue(pm.get("accounting_certificate_no").toString());
row.createCell(2).setCellValue(pm.get("booked_time").toString());
row.createCell(3).setCellValue(pm.get("campus_name").toString());
row.createCell(4).setCellValue(pm.get("storied_name").toString());
row.createCell(5).setCellValue(pm.get("address").toString());
row.createCell(6).setCellValue(pm.get("classify_code").toString());
row.createCell(7).setCellValue(pm.get("use_way").toString());
row.createCell(8).setCellValue(pm.get("building_structure").toString());
row.createCell(9).setCellValue(pm.get("up_floors").toString());
row.createCell(10).setCellValue(pm.get("down_floors").toString());
row.createCell(11).setCellValue(pm.get("completion_date").toString());
row.createCell(12).setCellValue(pm.get("is_own_title_deed").toString());
row.createCell(13).setCellValue(pm.get("title_deed_no").toString());
row.createCell(14).setCellValue(pm.get("title_deed_word").toString());
row.createCell(15).setCellValue(pm.get("right_unit_name").toString());
row.createCell(16).setCellValue(pm.get("split_area").toString());
row.createCell(17).setCellValue(pm.get("deed_use").toString());
row.createCell(18).setCellValue(pm.get("land_certificate_no").toString());
row.createCell(19).setCellValue(pm.get("land_certificate_word").toString());
row.createCell(20).setCellValue(pm.get("usable_area").toString());
row.createCell(21).setCellValue(pm.get("covered_area").toString());
row.createCell(22).setCellValue(pm.get("building_cost").toString());
row.createCell(23).setCellValue(pm.get("remark").toString());
setBorder(xwb,xSheet,rowget4,23);
/*这里不进行先加后创建新目录,会导致新数据写入旧目录*/
biao+=1;
if(biao-pagesize==0 || i == roomlist.size()-1){
//提取取消合并避免重复合并异常(第二次无法合并克隆过来合并好的列)
int xiayige = rowget4+1;
xSheet.removeMergedRegion(getMergedRegionIndex(xSheet, qingli, 0));//清理无用的合并单元格,小计
xSheet.removeMergedRegion(getMergedRegionIndex(xSheet, qingli+1, 0));//清理无用的合并单元格,合计
/*取消合并有问题,第一次会取消0行,干脆每次都取消合并下*/
xSheet.removeMergedRegion(getMergedRegionIndex(xSheet, 0, 0));//清理无用的合并单元格,合计
CellRangeAddress regions = new CellRangeAddress(0, 0, 0, 23);//开始行号与结束行号要大于大于等于
xSheet.addMergedRegion(regions);
XSSFRow sumcell = xSheet.getRow(xiayige)==null ? xSheet.createRow(xiayige) : xSheet.getRow(xiayige);//获取一行或创建一行
sumcell.createCell(0).setCellValue("小计:");
CellRangeAddress region = new CellRangeAddress(xiayige, xiayige, 0, 3);//开始行号与结束行号要大于大于等于
xSheet.addMergedRegion(region);
xSheet.getRow(xiayige).setHeight(toshort(1000));//小计高设置1000,合计设置高700
/*小计统计赋值*/
int sum = pagecount(cpage,pagesize);//用来统计计算的时候,从哪里开始统计
PgQuery obj = new PgQuery(sum,pagesize);
List<Map<String,Object>> total = detailReportMapper.excelSumStoriedTotal(obj);
Map<String,Object> m1;
String v1 = "0";
String v2 = "0";
String v3 = "0";
String v4 = "0";
if(total != null && total.get(0) != null){
m1 = total.get(0);
v1 = m1.get("split_area") == null ? "0" : m1.get("split_area").toString();
v2 = m1.get("usable_area") == null ? "0" : m1.get("usable_area").toString();
v3 = m1.get("covered_area") == null ? "0" : m1.get("covered_area").toString();
v4 = m1.get("building_cost") == null ? "0" : m1.get("building_cost").toString();
XSSFCellStyle cstyle = xwb.createCellStyle();
XSSFDataFormat df = xwb.createDataFormat();
cstyle.setDataFormat(df.getFormat("#,##0.00"));
xSheet.getRow(xiayige).createCell(16).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(16).setCellValue(v1);
xSheet.getRow(xiayige).createCell(20).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(20).setCellValue(v2);
xSheet.getRow(xiayige).createCell(21).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(21).setCellValue(v3);
xSheet.getRow(xiayige).createCell(22).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(22).setCellValue(v4);
setBorder(xwb, xSheet, xiayige, 23);
xSheet.getRow(xiayige).getCell(0).setCellStyle(cellStyle);
}
xiayige = rowget4+2;
XSSFRow sumcell_2 = xSheet.getRow(xiayige)==null ? xSheet.createRow(xiayige) : xSheet.getRow(xiayige);//获取一行或创建一行
sumcell_2.createCell(0).setCellValue("合计:");
CellRangeAddress region_2 = new CellRangeAddress(xiayige, xiayige, 0, 3);//开始行号与结束行号要大于大于等于
xSheet.addMergedRegion(region_2);
xSheet.getRow(xiayige).setHeight(toshort(700));//小计高设置1000,合计设置高700
/*总计统计赋值*/
List<Map<String,Object>> count = detailReportMapper.excelSumStoriedCount();
if(count != null && count.get(0) != null){
m1 = count.get(0);
v1 = m1.get("split_area") == null ? "0" : m1.get("split_area").toString();
v2 = m1.get("usable_area") == null ? "0" : m1.get("usable_area").toString();
v3 = m1.get("covered_area") == null ? "0" : m1.get("covered_area").toString();
v4 = m1.get("building_cost") == null ? "0" : m1.get("building_cost").toString();
XSSFCellStyle cstyle = xwb.createCellStyle();
XSSFDataFormat df = xwb.createDataFormat();
cstyle.setDataFormat(df.getFormat("#,##0.0"));
xSheet.getRow(xiayige).createCell(16).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(16).setCellValue(v1);
xSheet.getRow(xiayige).createCell(20).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(20).setCellValue(v2);
xSheet.getRow(xiayige).createCell(21).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(21).setCellValue(v3);
xSheet.getRow(xiayige).createCell(22).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(22).setCellValue(v4);
setBorder(xwb, xSheet, xiayige, 23);
xSheet.getRow(xiayige).getCell(0).setCellStyle(cellStyle);
}
cpage+=1;//页数+1
}
if(biao-pagesize==0){
biao = 0;
/*克隆创建新sheet,防止sheet重名*/
int num = zhengzetiqv(SheetName);
num+=1;
SheetName = "Sheet"+num;
for(int f = 0;f<999;f++){
if(xwb.getSheet(SheetName) == null){
xSheet = xwb.cloneSheet(0,SheetName);//克隆创建新sheet
for(int k = 4;k <= xSheet.getLastRowNum();k++){
//清理多余数据
if(xSheet.getRow(k) != null){
xSheet.removeRow(xSheet.getRow(k));
}
}
break;
}else{
num+=1;
SheetName = "Sheet"+num;
}
}
}
}
/*导出*/
FileOutputStream fileOutputStream = null;
String ph = "E:\\构筑物信息表" + System.currentTimeMillis() + ".xlsx";
System.out.println(ph);
fileOutputStream = new FileOutputStream(ph);//文件名必须拼接好
xwb.write(fileOutputStream);//HSSFWorkbook写入文件流
}
@Override
public List<Map<String, Object>> excelFindStoried() {
return detailReportMapper.excelFindStoried();
}
/**
* string转换成short类型
* @param ob
* @return
*/
public static Short toshort(Object ob) {
String val = String.valueOf(ob);
Short s = Short.valueOf(val);
return s;
}
/**
* 从字符串提取数字,使用正则表达式
* @param a
* @return
*/
public int zhengzetiqv(String a){
String regEx="[^0-9]";
int num;
if((a==null)||(a.equals(""))){
num = 0;
}else{
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(a);
String str = m.replaceAll("").trim();
if((str==null)||(str.equals(""))){
num = 0;
}else{
num = Integer.valueOf(str);
}
}
return num;
}
/**
* 用来清理合并的区域,获取区域 Region
* @param sheet
* @param row 开始行
* @param column 开始列
* @return
*/
public static int getMergedRegionIndex(Sheet sheet, int row, int column) {
int sheetMergeCount = sheet.getNumMergedRegions();
for (int i = 0; i < sheetMergeCount; i++) {
CellRangeAddress ca = sheet.getMergedRegion(i);
int firstColumn = ca.getFirstColumn();
int lastColumn = ca.getLastColumn();
int firstRow = ca.getFirstRow();
int lastRow = ca.getLastRow();
if (row >= firstRow && row <= lastRow) {
if (column >= firstColumn && column <= lastColumn) {
return i;
}
}
}
return 0;
}
/**
* 分页计算,从哪开始显示
* @param kaishiye 第几页
* @param tiaoshu 显示多少条
* @return limit 返回值是从哪一行开始
*/
public int pagecount(int kaishiye,int tiaoshu){
int ye = kaishiye; //第几页,第一页0开始
int tiao = tiaoshu; //显示多少条
ye = ye - 1; //(实际页数从0开始,所以提前-1)
int count = tiao * ((ye-1) + 1);
return count;
}
/**
* 设置边框样式
* @param xwb XSSFWorkbook对象
* @param xSheet XSSFSheet对象
* @param row 哪一行
* @param size 多少条(包括本数字)
*/
public void setBorder(XSSFWorkbook xwb,XSSFSheet xSheet,int row,int size){
XSSFCellStyle borderstyle = xwb.createCellStyle();
borderstyle.setBorderTop(BorderStyle.THIN);
borderstyle.setBorderBottom(BorderStyle.THIN);
borderstyle.setBorderLeft(BorderStyle.THIN);
borderstyle.setBorderRight(BorderStyle.THIN);
XSSFRow rows = xSheet.getRow(row) == null ? xSheet.createRow(row) : xSheet.getRow(row);
for (int i = 0; i <= size;i++){
if(rows.getCell(i) == null){
//空则创建
rows.createCell(i).setCellStyle(borderstyle);
}else{
rows.getCell(i).setCellStyle(borderstyle);
}
}
}
}
代码2.0,新的克隆导出,无需清理模板与取消合并(回头整理)
public XSSFWorkbook excelExportStoried(DetailReportQuery dr) throws Exception{
InputStream file = this.getClass().getResourceAsStream("/templates/statistics/templatesfileExcel/明细账.xlsx");
XSSFWorkbook xwb = new XSSFWorkbook(file);
String SheetName = "Sheet";
int cpage = 1;//默认第一页
int pagesize = 5000;//默认5000条
int colnum = 23;//最多多少列
int rowstart = 4;//从哪开始加载
int ji = 3;//设置小计与合计要合并的单元格
int clonenum = 0;
List<Map<String,Object>> roomlist = detailReportMapper.excelFindStoried(dr);
dr.setStartrow(dr.getStartSize());//开始行,每次都需要重新设置 limit
dr.setPageSize(pagesize);//条数 limit
dr.setTotalCount(roomlist.size());//总条数
dr.setCpage(cpage);//开始页
for(int i=0;i < (dr.getTotalPage()-1);i++){
//计算克隆几个初始模板,初始0默认有,-1个
xwb.cloneSheet(0);
}
XSSFSheet xSheet = xwb.getSheetAt(clonenum);//获取第0个
XSSFCellStyle cellStyle = xwb.createCellStyle();
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setAlignment(HorizontalAlignment.CENTER); //居中
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //垂直
int biao = 0;
for (int i = 0;i < roomlist.size();i++){
int rowget4 = rowstart+biao;
Map<String,Object> pm = roomlist.get(i);
XSSFRow row = xSheet.getRow(rowget4)==null ? xSheet.createRow(rowget4) : xSheet.getRow(rowget4);//获取一行或创建一行
row.createCell(0).setCellValue(pm.get("storied_no").toString());
row.createCell(1).setCellValue(pm.get("accounting_certificate_no").toString());
row.createCell(2).setCellValue(pm.get("booked_time").toString());
row.createCell(3).setCellValue(pm.get("campus_name").toString());
row.createCell(4).setCellValue(pm.get("storied_name").toString());
row.createCell(5).setCellValue(pm.get("address").toString());
row.createCell(6).setCellValue(pm.get("classify_code").toString());
row.createCell(7).setCellValue(pm.get("use_way").toString());
row.createCell(8).setCellValue(pm.get("building_structure").toString());
row.createCell(9).setCellValue(pm.get("up_floors").toString());
row.createCell(10).setCellValue(pm.get("down_floors").toString());
row.createCell(11).setCellValue(pm.get("completion_date").toString());
row.createCell(12).setCellValue(pm.get("is_own_title_deed").toString());
row.createCell(13).setCellValue(pm.get("title_deed_no").toString());
row.createCell(14).setCellValue(pm.get("title_deed_word").toString());
row.createCell(15).setCellValue(pm.get("right_unit_name").toString());
row.createCell(16).setCellValue(pm.get("split_area").toString());
row.createCell(17).setCellValue(pm.get("deed_use").toString());
row.createCell(18).setCellValue(pm.get("land_certificate_no").toString());
row.createCell(19).setCellValue(pm.get("land_certificate_word").toString());
row.createCell(20).setCellValue(pm.get("usable_area").toString());
row.createCell(21).setCellValue(pm.get("covered_area").toString());
row.createCell(22).setCellValue(pm.get("building_cost").toString());
row.createCell(23).setCellValue(pm.get("remark").toString());
setBorder(xwb,xSheet,rowget4,colnum);
/*这里不进行先加后创建新目录,会导致新数据写入旧目录*/
biao+=1;
/*小计合计设置*/
if(biao-pagesize==0 || i == roomlist.size()-1){
int xiayige = rowget4+1;
XSSFRow sumcell = xSheet.getRow(xiayige)==null ? xSheet.createRow(xiayige) : xSheet.getRow(xiayige);//获取一行或创建一行
sumcell.createCell(0).setCellValue("小计:");
CellRangeAddress region = new CellRangeAddress(xiayige, xiayige, 0, ji);//开始行号与结束行号要大于大于等于
xSheet.addMergedRegion(region);
xSheet.getRow(xiayige).setHeight(toshort(1000));//小计高设置1000,合计设置高700
List<Map<String,Object>> total = detailReportMapper.excelSumStoriedTotal(dr);
Map<String,Object> m1;
String v1 = "0";
String v2 = "0";
String v3 = "0";
String v4 = "0";
if(total != null && total.get(0) != null){
m1 = total.get(0);
v1 = m1.get("split_area") == null ? "0" : m1.get("split_area").toString();
v2 = m1.get("usable_area") == null ? "0" : m1.get("usable_area").toString();
v3 = m1.get("covered_area") == null ? "0" : m1.get("covered_area").toString();
v4 = m1.get("building_cost") == null ? "0" : m1.get("building_cost").toString();
XSSFCellStyle cstyle = xwb.createCellStyle();
XSSFDataFormat df = xwb.createDataFormat();
cstyle.setDataFormat(df.getFormat("#,##0.00"));
xSheet.getRow(xiayige).createCell(16).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(16).setCellValue(v1);
xSheet.getRow(xiayige).createCell(20).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(20).setCellValue(v2);
xSheet.getRow(xiayige).createCell(21).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(21).setCellValue(v3);
xSheet.getRow(xiayige).createCell(22).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(22).setCellValue(v4);
setBorder(xwb, xSheet, xiayige, colnum);
xSheet.getRow(xiayige).getCell(0).setCellStyle(cellStyle);
}
xiayige = rowget4+2;
XSSFRow sumcell_2 = xSheet.getRow(xiayige)==null ? xSheet.createRow(xiayige) : xSheet.getRow(xiayige);//获取一行或创建一行
sumcell_2.createCell(0).setCellValue("合计:");
CellRangeAddress region_2 = new CellRangeAddress(xiayige, xiayige, 0, ji);//开始行号与结束行号要大于大于等于
xSheet.addMergedRegion(region_2);
xSheet.getRow(xiayige).setHeight(toshort(700));//小计高设置1000,合计设置高700
/*总计统计赋值*/
List<Map<String,Object>> count = detailReportMapper.excelSumStoriedCount(dr);
if(count != null && count.get(0) != null){
m1 = count.get(0);
v1 = m1.get("split_area") == null ? "0" : m1.get("split_area").toString();
v2 = m1.get("usable_area") == null ? "0" : m1.get("usable_area").toString();
v3 = m1.get("covered_area") == null ? "0" : m1.get("covered_area").toString();
v4 = m1.get("building_cost") == null ? "0" : m1.get("building_cost").toString();
XSSFCellStyle cstyle = xwb.createCellStyle();
XSSFDataFormat df = xwb.createDataFormat();
cstyle.setDataFormat(df.getFormat("#,##0.00"));
xSheet.getRow(xiayige).createCell(16).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(16).setCellValue(v1);
xSheet.getRow(xiayige).createCell(20).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(20).setCellValue(v2);
xSheet.getRow(xiayige).createCell(21).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(21).setCellValue(v3);
xSheet.getRow(xiayige).createCell(22).setCellStyle(cstyle);
xSheet.getRow(xiayige).getCell(22).setCellValue(v4);
setBorder(xwb, xSheet, xiayige, colnum);
xSheet.getRow(xiayige).getCell(0).setCellStyle(cellStyle);
}
//制表人
String str = "";
String val = dr.getRoomName();
if(val != null && !val.equals("")){
str = val;
}
xSheet.getRow(1).getCell(0).setCellValue("制表人:"+str);
//制表单位
str = "";
val = dr.getManagementUnitName();
if(val != null && !val.equals("")){
str = val;
}
xSheet.getRow(1).getCell(10).setCellValue("制表单位:"+str);
//制表日期
str = "";
val = dr.getStartUseTime()==null ? "":dr.getStartUseTime().toString();
if(val != null && !val.equals("")){
Long timeStamp;
for(int q = 1;q <= 13;q++){
//不足13位补0
if(q > val.length()){
val+="0";
}
}
timeStamp = Long.valueOf(val);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
str = sdf.format(new Date(timeStamp));// 时间戳转换成时间
}
xSheet.getRow(1).getCell(21).setCellValue(str);
/*分页计算+1,更新页数与行数*/
cpage+=1;//页数+1
dr.setCpage(cpage);//开始页
dr.setStartrow(dr.getStartSize());//重新赋值开始行
}
/*克隆创建新sheet,防止sheet重名*/
if(biao-pagesize==0 && i != roomlist.size()-1){
biao = 0;
int num = zhengzetiqv(SheetName);
num+=1;
SheetName = "Sheet"+num;
for(int f = 0;f<999;f++){
if(xwb.getSheet(SheetName) == null){
clonenum+=1;
xSheet = xwb.getSheetAt(clonenum);
xwb.setSheetName(clonenum,SheetName);
break;
}else{
num+=1;
SheetName = "Sheet"+num;
}
}
}
}
return xwb;
}
/**
* string转换成short类型
* @param ob
* @return
*/
public static Short toshort(Object ob) {
String val = String.valueOf(ob);
Short s = Short.valueOf(val);
return s;
}
/**
* 从字符串提取数字,使用正则表达式
* @param a
* @return
*/
public int zhengzetiqv(String a){
String regEx="[^0-9]";
int num;
if((a==null)||(a.equals(""))){
num = 0;
}else{
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(a);
String str = m.replaceAll("").trim();
if((str==null)||(str.equals(""))){
num = 0;
}else{
num = Integer.valueOf(str);
}
}
return num;
}
/**
* 设置边框样式
* @param xwb XSSFWorkbook对象
* @param xSheet XSSFSheet对象
* @param row 哪一行
* @param size 多少条(包括本数字)
*/
public void setBorder(XSSFWorkbook xwb,XSSFSheet xSheet,int row,int size){
XSSFCellStyle borderstyle = xwb.createCellStyle();
borderstyle.setBorderTop(BorderStyle.THIN);
borderstyle.setBorderBottom(BorderStyle.THIN);
borderstyle.setBorderLeft(BorderStyle.THIN);
borderstyle.setBorderRight(BorderStyle.THIN);
XSSFRow rows = xSheet.getRow(row) == null ? xSheet.createRow(row) : xSheet.getRow(row);
for (int i = 0; i <= size;i++){
if(rows.getCell(i) == null){
//空则创建
rows.createCell(i).setCellStyle(borderstyle);
}else{
rows.getCell(i).setCellStyle(borderstyle);
}
}
}