banner
Hi my new friend!

山河浪漫,
人间温暖。

Scroll down

1.添加pom.xml依赖

<properties> <java.version>1.8</java.version> <hutool-poi.version>5.7.13</hutool-poi.version> <poi.version>4.1.2</poi.version> </properties> <dependencies> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-core</artifactId> <version>${hutool-poi.version}</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-poi</artifactId> <version>${hutool-poi.version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>${poi.version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>ooxml-schemas</artifactId> <version>1.4</version> </dependency> </dependencies>

2.编写代码文件

ExcelUtil.java文件

package com.cfm.demo.filedown; import cn.hutool.poi.excel.BigExcelWriter; import lombok.Synchronized; public class ExcelUtil { private static final String PATH = "/excel/"; private static final String SUFFIX = ".xlsx"; // Excel 列宽 private static final int COLUMN_WIDTH = 20; @Synchronized public static BigExcelWriter createBigExcelWriter(String fileName , int columnSize){ BigExcelWriter bigWriter = cn.hutool.poi.excel.ExcelUtil.getBigWriter(PATH + fileName + SUFFIX); for (int size = columnSize; size >= 0 ;size--){ bigWriter.setColumnWidth(size,COLUMN_WIDTH); } return bigWriter; } }

FileTest05.java文件

package com.cfm.demo.filedown; import cn.hutool.core.util.ReflectUtil; import cn.hutool.poi.excel.BigExcelWriter; import com.alibaba.fastjson.JSONObject; import org.apache.poi.openxml4j.opc.PackagePartName; import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.TargetMode; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFPictureData; import org.apache.poi.xssf.usermodel.XSSFRelation; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @Controller @RequestMapping("/file") public class FileTest05 { /** * 文件下载 */ @RequestMapping("/down5") public static void downloadFIle(HttpServletRequest request, HttpServletResponse response) { //数据准备工作 List<Object> list = new ArrayList<>(); Map<String, Object> map1 = new HashMap<>(); map1.put("kk.id", 11); map1.put("kk.name", "张三"); map1.put("kk.address", "北京"); map1.put("kk.age", "36"); Map<String, Object> map2 = new HashMap<>(); map2.put("kk.id", 22); map2.put("kk.name", "李四"); map2.put("kk.address", "上海"); map2.put("kk.age", "46"); list.add(map1); list.add(map2); System.out.println(JSONObject.toJSONString(list)); / String fileName = "文件名字"; // 创建一个Writer流 BigExcelWriter bigExcelWriter = ExcelUtil.createBigExcelWriter(fileName, 3); //BigExcelWriter bigExcelWriter = new BigExcelWriter(); //水印的内容 String watermarkInfo = "我是管理员呀"; try { //添加水印 Workbook workbook = bigExcelWriter.getWorkbook(); if (workbook instanceof SXSSFWorkbook) { insertWaterMarkTextToXlsx((SXSSFWorkbook) workbook, watermarkInfo); } else if (workbook instanceof XSSFWorkbook) { insertWaterMarkTextToXlsx((XSSFWorkbook) workbook, watermarkInfo); } // 获取下Header,判断是哪种浏览器下载文件,来解决文件名的编码命名问题 String header = request.getHeader("User-Agent").toUpperCase(); if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) { fileName = URLEncoder.encode(fileName, "utf-8"); fileName = fileName.replace("+", "%20"); //IE下载文件名空格变+号问题 } else { fileName = new String(fileName.getBytes(), "UTF8"); } // 有点重复,可以不重写上面的ExcelUtils类,这是防止数据量很大时,需要提前准备文件,并不是即时写入即时返回 String fileName1 = fileName + ".xlsx"; response.reset(); // 设置文件对应后缀的ContentType response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 返回的是流的形式 response.setContentType("application/octet-stream; charset=utf-8"); response.setHeader("Location", fileName1); response.setHeader("Cache-Control", "max-age=0"); // 这句的作用是会打开用户那边下载文件时的那个保存位置的框,如果文件名中有中文,建议编下码 response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName1, "UTF8")); AtomicInteger count = new AtomicInteger(); // 开始准备写入数据 for (Object obj : list) { // 将查询的数据转换为map Map<String, Object> map = (Map<String, Object>) obj; bigExcelWriter.writeRow(map, count.getAndIncrement() == 0); } bigExcelWriter.close(); // 上面的过程就是文件的写入过程并且保存在了/excel/目录下 // 下面就是把这个文件读取出来,以流的形式返回 File excelFile = new File("/excel/" + fileName1); FileInputStream fis = new FileInputStream(excelFile); // 文件流上面加一层缓冲流,目的为了加快速度,减少IO BufferedInputStream buff = new BufferedInputStream(fis); // 同理,输出流上也套了一层缓冲的输出流 BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream()); byte[] car = new byte[1024]; int l = 0; // 按字节读取文件 while (l < excelFile.length()) { int j = buff.read(car, 0, 1024); l += j; // 写入out流中 out.write(car, 0, j); } // 关闭流 fis.close(); buff.close(); out.close(); excelFile.delete(); } catch (Exception e) { e.printStackTrace(); } } /** * 给excel添加水印. * * @param workbook Xlsx的Excel工作簿. * @param waterMarkText 水印内容. * @throws IOException IO异常抛出 */ public static void insertWaterMarkTextToXlsx(SXSSFWorkbook workbook, String waterMarkText) throws IOException { BufferedImage image = createWatermarkImage(waterMarkText); ByteArrayOutputStream imageOs = new ByteArrayOutputStream(); ImageIO.write(image, "png", imageOs); int pictureIdx = workbook.addPicture(imageOs.toByteArray(), XSSFWorkbook.PICTURE_TYPE_PNG); XSSFPictureData pictureData = (XSSFPictureData) workbook.getAllPictures().get(pictureIdx); //获取每个Sheet表 for (int i = 0; i < workbook.getNumberOfSheets(); i++) { SXSSFSheet sheet = workbook.getSheetAt(i); //这里由于 SXSSFSheet 没有 getCTWorksheet() 方法,通过反射取出 _sh 属性 XSSFSheet shReflect = (XSSFSheet) ReflectUtil.getFieldValue(sheet, "_sh"); PackagePartName ppn = pictureData.getPackagePart().getPartName(); String relType = XSSFRelation.IMAGES.getRelation(); PackageRelationship pr = shReflect.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null); shReflect.getCTWorksheet().addNewPicture().setId(pr.getId()); } } /** * 生成水印图片. * * @param content 需要生成水印的文字信息. * @return 图片字节流. */ public static BufferedImage createWatermarkImage(String content) { final String[] textArray = content.split("\n"); //设置水印字体、大小 final Font font = new Font("TimesRoman", Font.PLAIN, 80); int width = 500; int height = 400; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 背景透明 开始 Graphics2D g = image.createGraphics(); image = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT); g.dispose(); // 背景透明 结束 g = image.createGraphics(); // 设定画笔颜色 g.setColor(new Color(Color.lightGray.getRGB())); // 设置画笔字体 g.setFont(font); // 设定倾斜度 // g.shear(0.1, -0.26); // 设置字体平滑 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //文字从中心开始输入,算出文字宽度,左移动一半的宽度,即居中 FontMetrics fontMetrics = g.getFontMetrics(font); // 水印位置 int x = width / 2; int y = height / 2; // 设置水印旋转 g.rotate(Math.toRadians(-40), x, y); for (String s : textArray) { // 文字宽度 int textWidth = fontMetrics.stringWidth(s); // 画出字符串 g.drawString(s, x - (textWidth / 2), y); y = y + font.getSize(); } // 释放画笔 g.dispose(); return image; } /** * 给excel添加水印. * * @param workbook Xls的Excel工作簿. * @param waterMarkText 水印内容. * @throws IOException IO异常抛出 */ public static void insertWaterMarkTextToXlsx(XSSFWorkbook workbook, String waterMarkText) throws IOException { BufferedImage image = createWatermarkImage(waterMarkText); ByteArrayOutputStream imageOs = new ByteArrayOutputStream(); ImageIO.write(image, "png", imageOs); int pictureIdx = workbook.addPicture(imageOs.toByteArray(), XSSFWorkbook.PICTURE_TYPE_PNG); XSSFPictureData pictureData = workbook.getAllPictures().get(pictureIdx); //获取每个Sheet表 for (int i = 0; i < workbook.getNumberOfSheets(); i++) { XSSFSheet sheet = workbook.getSheetAt(i); PackagePartName ppn = pictureData.getPackagePart().getPartName(); String relType = XSSFRelation.IMAGES.getRelation(); PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null); sheet.getCTWorksheet().addNewPicture().setId(pr.getId()); } } }

3.效果展示

启动本地服务,访问地址后下载的效果:
在这里插入图片描述

原文链接:https://blog.csdn.net/qidaihuimou/article/details/128805854

我很可爱,请给我钱

昵称
邮箱
0/200
  • OωO
  • |´・ω・)ノ
  • ヾ(≧∇≦*)ゝ
  • (☆ω☆)
  • (╯‵□′)╯︵┴─┴
  •  ̄﹃ ̄
  • (/ω\)
  • ∠( ᐛ 」∠)_
  • (๑•̀ㅁ•́ฅ)
  • →_→
  • ୧(๑•̀⌄•́๑)૭
  • ٩(ˊᗜˋ*)و
  • (ノ°ο°)ノ
  • (´இ皿இ`)
  • ⌇●﹏●⌇
  • (ฅ´ω`ฅ)
  • (╯°A°)╯︵○○○
  • φ( ̄∇ ̄o)
  • ヾ(´・ ・`。)ノ"
  • ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
  • (ó﹏ò。)
  • Σ(っ °Д °;)っ
  • ( ,,´・ω・)ノ"(´っω・`。)
  • ╮(╯▽╰)╭
  • o(*////▽////*)q
  • >﹏<
  • ( ๑´•ω•) "(ㆆᴗㆆ)
  • 😂
  • 😀
  • 😅
  • 😊
  • 🙂
  • 🙃
  • 😌
  • 😍
  • 😘
  • 😜
  • 😝
  • 😏
  • 😒
  • 🙄
  • 😳
  • 😡
  • 😔
  • 😫
  • 😱
  • 😭
  • 💩
  • 👻
  • 🙌
  • 🖕
  • 👍
  • 👫
  • 👬
  • 👭
  • 🌚
  • 🌝
  • 🙈
  • 💊
  • 😶
  • 🙏
  • 🍦
  • 🍉
  • 😣
  • 颜文字
  • Emoji
0 条评论