查詢的效果圖
表格數據結構
查看的表格效果圖
導出表格的Excel效果圖
控制層:
@ResponseBody
@RequestMapping(value = "excleDownload")
public void excleDownload(HttpServletRequest request, HttpServletResponse response,Integer id) throws IOException {
List<ljCheckInstanceM> ljListInfo = dailyInService.queryContentInfo(id);//查詢內容 ljCheckInstanceM是實體類
List<ljCheckInstanceM> ljListPhoto = dailyInService.queryPhotoInfo(id);//查詢id下對應的圖片
Map<String, String> fileQD = ExportExcelUtil.excleDownload(request.getServletContext(), null, ljListInfo, ljListPhoto);//生成Excel文件並返回地址
String excelPathP = fileQD.get("path");//路徑
String excelNameP = fileQD.get("name");//名稱
//文件流的方式導出Excel
try {
// 輸出響應正文的輸出流
OutputStream out;
// 讀取本地文件的輸入流
InputStream in;
// 獲得本地輸入流
File file = new File("C:\\"+ excelPathP + excelNameP);
in = new FileInputStream(file);
// 設置響應正文的MIME類型
response.setContentType("application/octet-stream;charset=UTF-8");
String fileName = new String(excelNameP.getBytes("gb2312"), "iso8859-1");
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
// 把本地文件發送給客戶端
out = response.getOutputStream();
int byteRead = 0;
byte[] buffer = new byte[512];
while ((byteRead = in.read(buffer)) != -1) {
out.write(buffer, 0, byteRead);
}
in.close();
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
logger.error("文件下載出現異常", e);
}
}
生成Excel的工具類
package com.cyl.util;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.cyl.model.ljCheckBodyTarget;
import com.cyl.model.ljCheckInstanceM;
public class ExportExcelUtil {
private static Logger log = Logger.getLogger(ExportExcelUtil.class);
/**
* 導出Excel
* @param context 上下文會話對象
* @param dicument 生成文件的目錄文件名,參數為空時默認為excel
* @param ljListInfo 類數據集
* @param ljListPhoto 類數據集-圖片地址
* @param sheetName sheet名稱
* @param title 標題
* @return
* @throws UnsupportedEncodingException
*/
public static Map<String, String> excleDownload(ServletContext context, String dicument,
List<ljCheckInstanceM> ljListInfo, List<ljCheckInstanceM> ljListPhoto) {
Map<String, String> result = new HashMap<String, String>();
//創建工作薄
XSSFWorkbook wb = new XSSFWorkbook();
//創建表格
XSSFSheet sheet = wb.createSheet();
//設置列寬
sheet.setColumnWidth(0,4000);
sheet.setColumnWidth(1,5500);
sheet.setColumnWidth(2,5700);
sheet.setColumnWidth(3,5700);
sheet.setColumnWidth(4,3500);
sheet.setColumnWidth(5,3500);
sheet.setColumnWidth(6,3500);
sheet.setColumnWidth(7,3500);
sheet.setColumnWidth(8,3500);
sheet.setColumnWidth(9,3500);
/*************邊框、居中、加粗、仿宋用於 標題樣式********************/
//創建樣式1
XSSFCellStyle style = wb.createCellStyle();
//設置背景色
style.setFillForegroundColor((short)71);//淺藍色
style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
//設置邊框樣式
style.setBorderBottom(CellStyle.BORDER_THIN);
style.setBorderLeft(CellStyle.BORDER_THIN);
style.setBorderRight(CellStyle.BORDER_THIN);
style.setBorderTop(CellStyle.BORDER_THIN);
// 指定單元格居中對齊
style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 指定單元格垂直居中對齊
style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
//設置字體
XSSFFont font = wb.createFont();
font.setFontName("仿宋_GB2312");//設置字體樣式
font.setColor((short)1);//設置字體顏色
font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);//粗體顯示
font.setFontHeightInPoints((short) 12);
style.setFont(font);//選擇需要用到的字體格式
/****************結束******************/
/*************邊框、居中、加粗、仿宋用於 副標題樣式********************/
//創建樣式1
XSSFCellStyle style1 = wb.createCellStyle();
//設置樣式
style1.setBorderBottom(CellStyle.BORDER_THIN);
style1.setBorderLeft(CellStyle.BORDER_THIN);
style1.setBorderRight(CellStyle.BORDER_THIN);
style1.setBorderTop(CellStyle.BORDER_THIN);
// 指定單元格居中對齊
style1.setAlignment(XSSFCellStyle.ALIGN_CENTER);
// 指定單元格垂直居中對齊
style1.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
//設置字體
XSSFFont font1 = wb.createFont();
font1.setFontName("仿宋_GB2312");
font1.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);//粗體顯示
font1.setFontHeightInPoints((short) 12);
style1.setFont(font1);//選擇需要用到的字體格式
/****************結束******************/
/****************用於內容設置樣式******************/
XSSFCellStyle style2 = wb.createCellStyle();//創建樣式2
style2.setBorderBottom(CellStyle.BORDER_THIN);
style2.setBorderLeft(CellStyle.BORDER_THIN);
style2.setBorderRight(CellStyle.BORDER_THIN);
style2.setBorderTop(CellStyle.BORDER_THIN);
style2.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 指定單元格居中對齊
style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);// 指定單元格垂直居中對齊
style2.setWrapText(true);//自動換行
//設置字體
XSSFFont font2 = wb.createFont();
font2.setFontName("仿宋_GB2312");
font2.setFontHeightInPoints((short) 12);
style2.setFont(font2);//選擇需要用到的字體格式
/****************結束******************/
/****************用於內容設置樣式3******************/
XSSFCellStyle style3 = wb.createCellStyle();//創建樣式2
style3.setFillForegroundColor((short)70);//淺灰色 顏色參考地址 https://blog.csdn.net/w779050550/article/details/81094221
style3.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
style3.setBorderBottom(CellStyle.BORDER_THIN);//設置邊框
style3.setBorderLeft(CellStyle.BORDER_THIN);
style3.setBorderRight(CellStyle.BORDER_THIN);
style3.setBorderTop(CellStyle.BORDER_THIN);
style3.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 指定單元格居中對齊
style3.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);// 指定單元格垂直居中對齊
//設置字體
XSSFFont font3 = wb.createFont();
font3.setFontName("仿宋_GB2312");
font3.setFontHeightInPoints((short) 12);
style3.setFont(font3);//選擇需要用到的字體格式
/****************結束******************/
//行
XSSFRow row = null;
FileOutputStream out = null;
String fileName = TUtil.format("yyyy_MM_dd_HHmmssSSSSSS");
// 日期格式轉爲字符串輸出
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String filePath = null;//路徑
CellRangeAddress region = null;//合併單元格
Cell cell = null;
BufferedImage bufferImg = null;
int index = 1;//序號計數
try {
row = sheet.createRow(0);//Excel表格第一行
cell = row.createCell(0);
cell.setCellStyle(style);
cell.setCellValue("詳細信息");
//合併單元格 first row last row first column last column
region = new CellRangeAddress(0, 0, 0, 8 );
sheet.addMergedRegion(region);
setBorderStyle(XSSFCellStyle.BORDER_THIN, region, sheet, wb); //給合併過的單元格加邊框
Map<String, Object> needmegMap = new HashMap<String,Object>();//爲了大項合併,name標記大項值,firstRow標記在Excel中的行號
Map<String, Object> needmegMapSub = new HashMap<String,Object>();//爲了子項合併,name標記大項值,firstRow標記在Excel中的行號
for (int i = 0; i < ljListInfo.size(); i++) {
ljCheckInstanceM data = ljListInfo.get(i);
if (i == 0) {
//爲了合併大項 初始化標記的map
needmegMap.put("firstRow", i + 3);//firstRow標記在Excel中的行號
needmegMap.put("name", "");//name標記大項值
needmegMapSub.put("firstRow", i + 3);//firstRow標記在Excel中的行號
needmegMapSub.put("name", "");//name標記子項值
fileName += "_"+ data.getSignature();//以時間+小區(單位)名爲文件名
fileName += ".xlsx";
row = sheet.createRow(1);//Excel表格第二行
cell = row.createCell(0);
cell.setCellStyle(style1);
cell.setCellValue("鎮/街道");
cell = row.createCell(1);
cell.setCellStyle(style2);
cell.setCellValue(data.getAttr1());
cell = row.createCell(2);
cell.setCellStyle(style1);
cell.setCellValue("小區(單位)名");
cell = row.createCell(3);
cell.setCellStyle(style2);
cell.setCellValue(data.getSignature());
cell = row.createCell(4);
cell.setCellStyle(style1);
cell.setCellValue("總得分");
region = new CellRangeAddress(1, 1, 4, 5 );
sheet.addMergedRegion(region);
setBorderStyle(XSSFCellStyle.BORDER_THIN, region, sheet, wb); //給合併過的單元格加邊框
cell = row.createCell(6);
cell.setCellStyle(style2);
cell.setCellValue(data.getTotalScore());
cell = row.createCell(7);
cell.setCellStyle(style1);
cell.setCellValue("檢查日期");
String endTIme = sdf.format(data.getCheckDate());
cell = row.createCell(8);
cell.setCellStyle(style2);
cell.setCellValue(endTIme);
row = sheet.createRow(2);//Excel表格第三行
cell = row.createCell(0);
cell.setCellStyle(style1);
cell.setCellValue("序號");
cell = row.createCell(1);
cell.setCellStyle(style1);
cell.setCellValue("檢查內容");
cell = row.createCell(2);
cell.setCellStyle(style1);
cell.setCellValue("檢查子項");
cell = row.createCell(3);
cell.setCellStyle(style1);
cell.setCellValue("指標");
cell = row.createCell(4);
cell.setCellStyle(style1);
cell.setCellValue("評分");
cell = row.createCell(5);
cell.setCellStyle(style1);
cell.setCellValue("說明");
cell = row.createCell(6);
cell.setCellStyle(style1);
cell.setCellValue("圖片");
region = new CellRangeAddress(2, 2, 6, 8);
sheet.addMergedRegion(region);
setBorderStyle(XSSFCellStyle.BORDER_THIN, region, sheet, wb); //給合併過的單元格加邊框
}
if(i == 0 || i > 0){
row = sheet.createRow(i + 3);//動態創建第四行...N行
//檢查內容 大項合併行
cell = row.createCell(1);
cell.setCellStyle(style2);
cell.setCellValue(data.getAttr2());
if (!needmegMap.get("name").equals(data.getAttr2())) {
cell = row.createCell(0);
cell.setCellStyle(style2);
cell.setCellValue(index++);
if (!needmegMap.get("name").equals("")) {
region = new CellRangeAddress((int) needmegMap.get("firstRow"), i + 3 - 1, 0, 0);//合併單元格(開始行,結束行,開始列,結束列)
sheet.addMergedRegion(region);
region = new CellRangeAddress((int) needmegMap.get("firstRow"), i + 3 - 1, 1, 1);
sheet.addMergedRegion(region);
setBorderStyle(XSSFCellStyle.BORDER_THIN, region, sheet, wb); //給合併過的單元格加邊框
}
needmegMap.put("firstRow", i + 3);
needmegMap.put("name", data.getAttr2());
}
if (i == ljListInfo.size() - 1) {//最後一個合併
if (!needmegMap.get("name").equals("")) {
region = new CellRangeAddress((int) needmegMap.get("firstRow"), ljListInfo.size() + 2, 0, 0);
sheet.addMergedRegion(region);
setBorderStyle(XSSFCellStyle.BORDER_THIN, region, sheet, wb); //給合併過的單元格加邊框
region = new CellRangeAddress((int) needmegMap.get("firstRow"), ljListInfo.size() + 2, 1, 1);
sheet.addMergedRegion(region);
setBorderStyle(XSSFCellStyle.BORDER_THIN, region, sheet, wb); //給合併過的單元格加邊框
}
}
cell = row.createCell(2);
cell.setCellStyle(style2);
cell.setCellValue(data.getAttr3());
if (!needmegMapSub.get("name").equals(data.getAttr3())) {
if (!needmegMapSub.get("name").equals("")) {
region = new CellRangeAddress((int) needmegMapSub.get("firstRow"), i + 3 - 1, 2, 2);
sheet.addMergedRegion(region);
setBorderStyle(XSSFCellStyle.BORDER_THIN, region, sheet, wb); //給合併過的單元格加邊框
}
needmegMapSub.put("firstRow", i + 3);
needmegMapSub.put("name", data.getAttr3());
}
if (i == ljListInfo.size() - 1) {//最後一個合併
if (!needmegMapSub.get("name").equals("")) {
region = new CellRangeAddress((int) needmegMapSub.get("firstRow"), ljListInfo.size() + 2, 2, 2);
sheet.addMergedRegion(region);
setBorderStyle(XSSFCellStyle.BORDER_THIN, region, sheet, wb); //給合併過的單元格加邊框
}
}
cell = row.createCell(3);
cell.setCellStyle(style2);
cell.setCellValue(data.getAttr4());
cell = row.createCell(4);
cell.setCellValue(data.getsScore());
double sScore = data.getStandardScore();
double Score = data.getsScore();
if (sScore > Score) {
cell.setCellStyle(style3);
}else {
cell.setCellStyle(style2);
}
cell = row.createCell(5);
cell.setCellStyle(style2);
cell.setCellValue(data.getSignature2());
cell = row.createCell(6);
cell.setCellStyle(style2);
cell = row.createCell(7);
cell.setCellStyle(style2);
cell = row.createCell(8);
cell.setCellStyle(style2);
}
if (data.getAttr6() != null) {
int col = 6;//記錄當前開始列
for (int j = 0; j < ljListPhoto.size(); j++) {
ljCheckInstanceM dataPh = ljListPhoto.get(j);
if (data.getAttr6().equals(dataPh.getAttr2())) {
row.setHeight((short)1500);//設置行高度
// 先把讀進來的圖片放到一個ByteArrayOutputStream中,以便產生ByteArray
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
try {
String file = "C:\\" + dataPh.getAttr4();//獲取地址
bufferImg = ImageIO.read(new File(file));
ImageIO.write(bufferImg, "png", byteArrayOut);
} catch (IOException e) {
//e.printStackTrace();
continue;
}
XSSFDrawing patriarch = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, col, i + 3, col + 1, i + 4);
// 插入圖片
patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), XSSFWorkbook.PICTURE_TYPE_JPEG));
sheet.setColumnWidth(col, 256 * 20);//列寬
col++;
}
}
}
}
String relpath = (StringUtils.isBlank(dicument) ? "excel" : dicument) + "/";
filePath = "C:\\" + relpath;// 文件存放路徑
File fileDir = new File(filePath);
if (!(fileDir.exists() && fileDir.isDirectory())) {
new File(filePath).mkdirs();
}
result.put("path", relpath);
result.put("name", fileName);
out = new FileOutputStream(filePath + fileName);
wb.write(out);
} catch (FileNotFoundException e) {
e.printStackTrace();
log.error(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
log.error(e.getMessage());
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;// 返回下載結果
}
//解決合併單元格邊框顯示不完整的問題
public static void setBorderStyle(int border, CellRangeAddress region, XSSFSheet sheet, XSSFWorkbook wb){
RegionUtil.setBorderBottom(border, region, sheet, wb); //下邊框
RegionUtil.setBorderLeft(border, region, sheet, wb); //左邊框
RegionUtil.setBorderRight(border, region, sheet, wb); //右邊框
RegionUtil.setBorderTop(border, region, sheet, wb); //上邊框
}
}
基礎類
package com.cyl.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.log4j.Logger;
/**
* 基礎類
*
* @author Qiang1_Zhang
*/
public class TUtil {
static Logger log = Logger.getLogger(TUtil.class);
/**
* 日期轉換函數
*
* @param format
* 需要轉換的格式
* @return 轉換後的日期
*/
public static String format(String format) {
return new SimpleDateFormat(format).format(new Date());
}
/**
* 日期轉換函數
*
* @param format
* 需要轉換的格式
* @return 轉換後的日期
*/
public static String format(Date date, String format) {
return new SimpleDateFormat(format).format(date);
}
/**
* 打印函數
*
* @param str
* 對象類型
*/
public static void print(Object str) {
System.out.println(str);
}
/**
* 計算距今指定天數的日期
*
* @param day
* 相差的天數,可爲負數
* @return 計算之後的日期
*/
public static String GetDay(int day) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
cal.setTime(new Date());// 設置日曆時間
cal.add(Calendar.DAY_OF_MONTH, day);// 天數
String strDate = sdf.format(cal.getTime());// 得到你想要的天數
return strDate;
}
/**
* 獲取報表模板路徑
*
* @return
*/
public static String getURL() {
String dir = System.getProperty("user.dir");
print("dir=" + dir);
dir = dir.substring(0, dir.lastIndexOf("\\"));
String filePath = dir;
return filePath;
}
/**
* String類型日期轉換爲長整型
*
* @param date
* String類型日期
* @param format
* 日期格式
* @return long
*/
public static long strDateToLong(String date, String... format) {
String format1 = null;
if (format.length != 0) {
format1 = format[0];
} else {
format1 = "yyyy-MM-dd HH:mm:ss";
}
String sDt = date;
SimpleDateFormat sdf = new SimpleDateFormat(format1);
long lTime = 0;
try {
Date dt2 = sdf.parse(sDt);
lTime = dt2.getTime();
print(lTime);
} catch (ParseException e) {
e.printStackTrace();
}
return lTime;
}
public static void longToString(long l) {
format("");
}
/**
* 獲取文件創建時間
*
* @param file
* 文件目錄
*/
public static String getCreateTime(File file) {
// file = new File("e:/1.xls");
String date = "";
// file.lastModified();
try {
Process process = Runtime.getRuntime().exec(
"cmd.exe /c dir " + file.getAbsolutePath() + "/tc");
InputStream is = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
for (int i = 0; i < 5; i++) {// 前五行是其他的信息
br.readLine();
}
String createDateLine = br.readLine();
StringTokenizer tokenizer = new StringTokenizer(createDateLine);
date = tokenizer.nextToken() + " " + tokenizer.nextToken();
br.close();
// print(date);
} catch (IOException e) {
log.error("" + e.getMessage());
}
return date;
}
/**
* 獲取文件最後修改時間
*
* @param filePath
* 文件目錄
*/
public static void getLastModifyTime(File filePath) {
filePath = new File(
"\\\\10.131.18.8\\rt3生產機種\\ProductionReprot\\TraceAlterReprot-reprot");
File[] list = filePath.listFiles();
// for(File file : list){
// print(file.getAbsolutePath()+"\tcreate time:"+getCreateTime(file));
// }
for (File file : list) {
Date date = new Date(file.lastModified());
print(format(date, "yyyy-MM-dd"));
}
}
public static void getFile() {
String root = "\\\\10.131.18.8\\rt3生產機種\\ProductionReprot";
File filePath = new File(root);
File[] list = filePath.listFiles();
for (File file : list) {
print(file.getName()
+ "\t"
+ new File(file.getAbsolutePath() + "\\"
+ TUtil.format("yyyy-MM-dd") + ".xls").exists());
}
}
static void test() {
String today = TUtil.format("yyyy-MM-dd");
String dest = ReadProperties.ReadProprety("server.report.path")
+ "TraceAlterReprot-reprot" + "\\" + today + "\\";
print(dest);
File dir = new File(dest);// 創建當天目錄
if (!dir.exists()) {
dir.mkdir();
}
}
public static void getTimeDifference() {
try {
Date d1 = new SimpleDateFormat("yyyy-MM-dd").parse("2014-09-15");
Date d2 = new SimpleDateFormat("yyyy-MM-dd").parse("2014-09-14");
print((d2.getTime() - d1.getTime()) / 1000 / 60 / 60 / 24);
} catch (ParseException e) {
e.printStackTrace();
}
}
public List<String> distinctList(List<String> list) {
HashSet<String> h = new HashSet<String>(list);
list.clear();
list.addAll(h);
return list;
}
public List<Object> removeDuplicate(List<Object> list) {
HashSet<Object> h = new HashSet<Object>(list);
list.clear();
list.addAll(h);
return list;
}
/**
* 獲取四捨五入的整數
* @param input 乘數
* @param rate 比率
* @return 取整後的結果
*/
public double getRound(int input,double rate){
double tmp = input * rate;
return Math.round(tmp);
}
/**
* 獲取四捨五入的整數
* @param input 乘數
* @param rate 比率
* @return 取整後的結果
*/
public double ceil(int input,double rate){
double tmp = input * rate;
return Math.ceil(tmp);
}
}
前端
/* 我這裏是動態拼接的,摘取下載按鈕那一條,僅供參考 */
...省略
str += "<a class='btt btn-link' data-title='詳細信息' onclick = 'excleDownload("+ data[i].id +")' href='javascript:;'><i class='Hui-iconfont'></i> 下載</a>";
...省略
//方法
//下載文件
function excleDownload(id) {
window.location.href = "<%=basePath%>inspection/excleDownload.cyl?id="+ id;
}