java 实现Excel导出

2023-01-01 00:00:00 excel java 导出

1.注入相关依赖


        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>

2.相关工具类

public class ExcelUtils {
	/**
	 * Excel导出设置Workbook
	 * @param title 导出Excel文件名称
	 * @param rowList 第一个List为表头,其余行为表数据
	 * @param downLoadPic 是否下载图片
	 * @throws IOException
	 */
	public static HSSFWorkbook warpSingleWorkbook(String title, List<List<Object>> rowList, Boolean downLoadPic,Integer pos) throws IOException {
		if (rowList == null || rowList.isEmpty()) {
			throw new NullPointerException("the row list is null");
		}
		HSSFWorkbook book = new HSSFWorkbook();
		// 创建表
		HSSFSheet sheet = book.createSheet(title);
		// 设置单元格默认宽度为20个字符
		sheet.setDefaultColumnWidth(20);
		HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
		// 设置表头样式
		HSSFCellStyle style = book.createCellStyle();
		// 设置居左
		style.setAlignment(HorizontalAlignment.LEFT);
		// 检测表头数据(表头不允许数据为空)
		List<Object> head = rowList.get(0);
		// 写数据
		int size = rowList.get(0).size();
		// 第几行
		for (int i = 0; i < rowList.size(); i++) {
			List<Object> row = rowList.get(i);
			if (row == null || row.isEmpty()) {
				book.close();
				throw new NullPointerException("the "+(i+1)+"th row is null");
			}
			if (size != row.size()) {
				book.close();
				throw new IllegalArgumentException("the cell number of "+(i+1)+"th row is different form the first");
			}
			HSSFRow sr = sheet.createRow(i);
			// 第几列
			for (int j = 0; j < row.size(); j++) {
				// 如果是否下载照片选择了true,由于我们的照片放在第三列,即当循环到序列为2的时候获取到网络图片地址,这里还考虑到了有多张照片的情况,且用逗号拼接成多张照片。
				if (downLoadPic && i > 0 && j == pos) {
					if(StringUtils.isNotBlank(row.get(j).toString())){
						sr.setHeight((short) (1800));
						row.forEach(System.out::println);
						List<String> images = Arrays.asList(row.get(j).toString().split(","));
						int temp = j;
						for(String image : images){
							// 调用封装好的下载图片方法
							drawPictureInfoExcel(book, patriarch, i, j, image);
							j++;
						}
					}
				} else {
					setExcelValue(sr.createCell(j), row.get(j), style);
				}
			}
		}
		return book;
	}

	/**
	 * 设置Excel浮点数可做金额等数据统计
	 * @param cell 单元格类
	 * @param value 传入的值
	 */
	public static void setExcelValue(HSSFCell cell, Object value, HSSFCellStyle style){
		// 写数据
		if (value == null) {
			cell.setCellValue("");
		}else {
			if (value instanceof Integer || value instanceof Long) {
				cell.setCellType(CellType.NUMERIC);
				cell.setCellValue(Long.valueOf(value.toString()));
			} else if (value instanceof BigDecimal) {
				cell.setCellType(CellType.NUMERIC);
				cell.setCellValue(((BigDecimal)value).setScale(3, RoundingMode.HALF_UP).doubleValue());
			} else {
				cell.setCellValue(value.toString());
			}
			cell.setCellStyle(style);
		}
	}

	/**
	 *
	 * @param wb
	 * @param patriarch
	 * @param rowIndex
	 * @param columnIndex
	 * @param pictureUrl
	 */
	private static void drawPictureInfoExcel(HSSFWorkbook wb,HSSFPatriarch patriarch,int rowIndex, int columnIndex,String pictureUrl){
		//rowIndex代表当前行
		try {
			URL url = new URL(pictureUrl);
			//打开链接
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			//设置请求方式为"GET"
			conn.setRequestMethod("GET");
			//超时响应时间为5秒
			conn.setConnectTimeout(5 * 1000);
			//通过输入流获取图片数据
			InputStream inStream = conn.getInputStream();
			//得到图片的二进制数据,以二进制封装得到数据,具有通用性
			byte[] data = readInputStream(inStream);
			//anchor主要用于设置图片的属性
			// dx1:起始单元格的x偏移量,
			// dy1:起始单元格的y偏移量,
			// dx2:终止单元格的x偏移量,
			// dy2:终止单元格的y偏移量,
			// col1:起始单元格列序号,从0开始计算;
			// row1:起始单元格行序号,从0开始计算,
			// col2:终止单元格列序号,从0开始计算;
			// row2:终止单元格行序号,从0开始计算,
			HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 250,(short) columnIndex, rowIndex, (short) columnIndex, rowIndex);
			//Sets the anchor type (图片在单元格的位置)
			//0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
			anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
			patriarch.createPicture(anchor, wb.addPicture(data, HSSFWorkbook.PICTURE_TYPE_PNG));
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static byte[] readInputStream(InputStream inStream) throws Exception{
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		//创建一个Buffer字符串
		byte[] buffer = new byte[1024];
		//每次读取的字符串长度,如果为-1,代表全部读取完毕
		int len = 0;
		//使用一个输入流从buffer里把数据读取出来
		while( (len=inStream.read(buffer)) != -1 ){
			//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
			outStream.write(buffer, 0, len);
		}
		//关闭输入流
		inStream.close();
		//把outStream里的数据写入内存
		return outStream.toByteArray();
	}

3.实现代码

3.1构建工具里所需要的参数

//图片位置
Integer pos = 0;
//是否下载图片
boolean downLoadPic = false;
//构建list存放数据 每个List<Object>代表表格的一行
List<List<Object>> rowList = new ArrayList<List<Object>>();
//获取输出流
ServletOutputStream out = response.getOutputStream();

3.2调用工具类 进行导出

//调用提供的工具类   
HSSFWorkbook wb = ExcelUtils.warpSingleWorkbook("表格名称", rowList, downLoadPic, pos);
//设置响应规则
response.setContentType("application/x-download");
response.setCharacterEncoding("UTF-8");
response.addHeader("Content-Disposition", "attachment;filename=" + "表格名称.xls");
//关闭流
wb.write(out);
out.flush();
out.close();
wb.close();

    原文作者:碟碟以碟以喋喋
    原文地址: https://blog.csdn.net/weixin_52446536/article/details/126428558
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章