工具类——Java导出EXCEL2(设置样式、加载并填充图片、加载指定模板、大数据量设置窗口大小与刷新频率)

这篇具有很好参考价值的文章主要介绍了工具类——Java导出EXCEL2(设置样式、加载并填充图片、加载指定模板、大数据量设置窗口大小与刷新频率)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

书接上篇:工具类——Java 浏览器导入、导出Excel(Java import、export)demo
工具类——Java导出EXCEL2(设置样式、加载并填充图片、加载指定模板、大数据量设置窗口大小与刷新频率)
POI的导出方式:创建/加载Workbook,设置样式,填充数据,然后生成本地临时文件,最终以浏览器的形式打开,完成整个导出动作。

一、POI设置样式

demo如下,

private void setCellStyleDemo(T wb, T sheet) {
	def row1 = sheet.createRow(1)
	// 创建style并设置样式
    CellStyle style1 = wb.createCellStyle()
    style1.setWrapText(true)// 文本自动换行
    style1.setAlignment(HorizontalAlignment.CENTER)// 水平居中
    style1.setVerticalAlignment(VerticalAlignment.CENTER)// 垂直居中
    style1.setBorderLeft(BorderStyle.THIN)// 设置左边框
    style1.setBorderTop(BorderStyle.THIN)// 设置上边框
    style1.setBorderRight(BorderStyle.THIN)// 设置右边框
    style1.setBorderBottom(BorderStyle.THIN)// 设置下边框
    // 设置字体
	Font font1 = wb.createFont()
    font1.setFontHeight(11)// 大小
    font1.setBold(true)// 加粗与否
    style1.setFont(font1)
    // 填充单元格value为“序号”,并未它设置以上样式
    row1.createCell(0).setCellValue("序号")
    row1.getCell(0).setCellStyle(style1)
    
    // 设置列宽、行高
    sheet.setColumnWidth(0, 5 * 256)// 设置第一列宽度为5个字符宽度
    for (int i = 1; i <= len; i++) {
        sheet.setColumnWidth(i, 20 * 256)// 设置第二至…宽度为20个字符宽度
    }
    row0.setHeightInPoints(50)// 设置第1行高度为50px
}

二、POI导出图片

demo如下,

 /**
     * 加载头像,并填充
     * @param wb (xlsx)
     * @param sheet 页签
     * @param imgUrl 图片路径
     * @return 是否填充图片:否,填充(2寸照片)的字眼
     */
    boolean setPngToSheet(XSSFWorkbook wb, XSSFSheet sheet, String imgUrl) {
        if (imgUrl.indexOf(".") == -1) {
            return false
        }
        String imgType = imgUrl.substring(imgUrl.indexOf(".") + 1)// jpg、png…
        FileInputStream fs
        ByteArrayOutputStream baos
        try {
            File imgFile = new File(imgUrl)
            fs = new FileInputStream(imgFile)
            baos = new ByteArrayOutputStream()
            BufferedImage bi = ImageIO.read(fs)
            // 图片入流
            ImageIO.write(bi, imgType, baos)
            // 写入excel
            XSSFDrawing patriarch = sheet.createDrawingPatriarch()
            // 图片导入指定单元格
            XSSFClientAnchor anchor = new XSSFClientAnchor(350, 100, 150, 0, (short) 8, 2, (short) 9, 6)

            int type
            switch (imgType) {
                case "png":
                    type = XSSFWorkbook.PICTURE_TYPE_PNG
                    break
                case "jpg":
                    type = XSSFWorkbook.PICTURE_TYPE_JPEG
                    break
                default:
                    type = 6// PNG
            }
            // 插入图片
            patriarch.createPicture(anchor, wb.addPicture(baos.toByteArray(), type))
        } catch (Exception ex) {
            logger.error("个人图片插入失败", ex)
            return false
        } finally {
            if (fs != null) {
                fs.close()
            }
            if (baos != null) {
                baos.close()
            }
        }

        return true
    }

1.解释XSSFClientAnchor

XSSFClientAnchor anchor = new XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2)

👉源码,

/**
     * Creates a new client anchor and sets the top-left and bottom-right
     * coordinates of the anchor by cell references and offsets.
     * Sets the type to {@link AnchorType#MOVE_AND_RESIZE}.
     *
     * @param dx1  the x coordinate within the first cell.
     * @param dy1  the y coordinate within the first cell.
     * @param dx2  the x coordinate within the second cell.
     * @param dy2  the y coordinate within the second cell.
     * @param col1 the column (0 based) of the first cell.
     * @param row1 the row (0 based) of the first cell.
     * @param col2 the column (0 based) of the second cell.
     * @param row2 the row (0 based) of the second cell.
     */
    public XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) {
        anchorType = AnchorType.MOVE_AND_RESIZE;
        cell1 = CTMarker.Factory.newInstance();
        cell1.setCol(col1);
        cell1.setColOff(dx1);
        cell1.setRow(row1);
        cell1.setRowOff(dy1);
        cell2 = CTMarker.Factory.newInstance();
        cell2.setCol(col2);
        cell2.setColOff(dx2);
        cell2.setRow(row2);
        cell2.setRowOff(dy2);
    }

👉解释,

  • dx1:表示图片左上角相对于单元格左边界的X轴偏移量,单位为英寸/EMU;
  • dy1:表示图片左上角相对于单元格顶部边界的Y轴偏移量,单位为英寸/EMU;
  • dx2:表示图片右下角相对于单元格左下角的X轴偏移量,单位为英寸/EMU;
  • dy2:表示图片右下角相对于单元格左下角的Y轴偏移量,单位为英寸/EMU;
  • col1:表示该锚点对应的起始单元格列号,从0开始计数;
  • row1:表示该锚点对应的起始单元格行号,从0开始计数;
  • col2:表示该锚点对应的结束单元格列号,从0开始计数;
  • row2:表示该锚点对应的结束单元格行号,从0开始计数。

👉例如,
XSSFClientAnchor anchor = new XSSFClientAnchor(350, 100, 150, 0, (short) 8, 2, (short) 9, 6)

1)后四位,设置图片位置:

  • 左上角位于:第9列,第3行
  • 右下角位于:第10列,第7行

2)前四位,设置图片收缩距离:

  • 与左侧间隔350英寸/EMU
  • 与上侧间隔100英寸/EMU
  • 与右侧间隔150英寸/EMU
  • 与下侧间隔0英寸/EMU
    工具类——Java导出EXCEL2(设置样式、加载并填充图片、加载指定模板、大数据量设置窗口大小与刷新频率)

三、加载指定模板导出

demo如下,

/**
    * 加载指定模板
    * @param path 文件路径
    * @return 返回Workbook,可指定XSSFWorkbook或者SXSSFWorkbook
    */
   private Workbook readTemplateFile(String path) {
       FileInputStream fs
       Workbook wb = null
       try {
           File temFile = new File(path)
           fs = new FileInputStream(temFile)
           // 读取模板文件
           wb = new Workbook(fs)
       } catch (Exception ex) {
           logger.error("加载EXCEL模板失败", ex)
       } finally {
           if (fs != null) {
               fs.close()
           }
       }
       return wb
   }

四、👉Workbook、XSSFWorkbook与SXSSFWorkbook

Workbook是XSSFWorkbook与SXSSFWorkbook的父类,可以用父类指向子类来调用不确定的子类方法。

XSSFWorkbook和SXSSFWorkbook都是Java中Apache POI库提供的用于操作Excel文档的对象,其中XSSFWorkbook是基于内存模型(in-memory model)实现的,而SXSSFWorkbook则是基于流的方式(streaming way)实现的。

区别主要体现在以下两个方面:

1、内存占用:XSSFWorkbook会将整个Excel文档加载到内存中,因此在处理大量数据时,需要消耗大量的内存。而SXSSFWorkbook采用基于流的方式,将一个sheet中的数据分段写入磁盘以避免内存溢出,因此能够更好地处理海量数据,并且占用的内存较少。

2、性能表现:由于SXSSFWorkbook采用了基于流的方式进行Excel文件的操作,使得其性能表现优于XSSFWorkbook,尤其是对于导出海量数据的情况下,SXSSFWorkbook的速度可能会显著快于XSSFWorkbook。

因此,建议在处理大规模Excel数据时,选择采用SXSSFWorkbook对象,而在需求较小的情况下,XSSFWorkbook也可以满足相关操作需求。

1.大数据量导出

注意点一:
SXSSFWorkbook wb = new SXSSFWorkbook()
初始化时,未指定窗口大小,默认使用100.

1、在写入数据时,只有在当前窗口内的数据才会被缓存到内存中,之外的数据将直接写入到硬盘上,并且该窗口会随着当前位置的移动而进行滚动更新
2、缓存窗口的大小一般需要根据具体应用场景和系统资源情况来确定,并没有一个固定的标准。缓存窗口可以理解为内存中的缓存区,它用于暂时存储待处理的数据或文件,并能够提高程序的读写速度和响应时间。
3、 在实际应用中,选择合适的缓存窗口大小需要考虑多个因素,包括数据大小、读写频率、系统内存大小、CPU处理能力等,以及操作系统、数据库、网络传输等其他相关因素。通常情况下,我们可以通过建立模拟测试环境来评估不同缓存窗口大小对系统性能的影响,并根据测试结果进行调整和优化。

注意点二:
其中数据量大时,使用SXSSFWorkbook需要:

if (sheet instanceof SXSSFWorkbook) {
    // 一些情况下,可能会在循环遍历过程中频繁地创建行(Row)对象,此时执行完一定数量的行(Row)对象后,调用flushRows方法可以显式地告知系统将缓存数据写入磁盘,降低内存占用(避免OOM)。
    ((SXSSFSheet) sheet).flushRows()
}

1、一般来说,flushRows方法的调用频率取决于内存使用情况和可用内存的大小。如果数据量很大,内存持续占用,就需要更加频繁地调用flushRows方法,以便及时释放内存。
2、 具体来说,可以根据系统的可用内存、JVM的堆内存设置以及数据集合所需内存的大小等变化情况,适当调整flushRows方法的使用策略。常见的建议是每3000~5000行调用一次flushRows方法,这样可以有效地平衡内存占用和程序性能。
3、特别是在处理大数据集时,推荐使用SXSSF工作簿,并结合设置缓存窗口大小的方式来优化性能:通过SXSSFWorkbook类的setRowAccessWindowSize(int rowAccessWindowSize)方法,来设置缓存窗口大小,在写入数据时,只有在当前窗口内的数据才会被缓存到内存中,之外的数据将直接写入到硬盘上,并且该窗口会随着当前位置的移动而进行滚动更新,从而实现最大程度的内存优化。

1)根据数据量选择XSSFWorkbook,还是SXSSFWorkbook

已有一套XSSFWorkbook导出,但是当数据量较大时(假如3000条以上),我想使用SXSSFWorkbook流式导出

demo如下,
在我保留XSSFWorkbook的前提下,数据量大使用SXSSFWorkbook,数据量小依旧使用XSSFWorkbook,


    def exportPersonPool(@Nullable Object... args) {      
        try {
            // 查询数据量
            Long count = 2000// 查询数据库,统计待导出数据总数
            
            def wb
            if (count > PERSON_MAX_SIZE) {
                wb = exportPersonPoolLarge(args, count)
            } else {
                wb = exportPersonPoolSmall(args)
            }
            // 生成导出路径,略
            return MyExcelUtil.getMyExportExcel(wb, String.format("测试导出表%s%s",System.currentTimeMillis(), ExcelUtil.XLSX))
        } catch (Exception ex) {
            logger.error("导出失败", ex)
        }
    }

    /**
     * 大数据量
     */
    SXSSFWorkbook exportPersonPoolLarge(@Nullable Object... args, Long count) {
    	// 使用默认窗口大小100
        SXSSFWorkbook wb = new SXSSFWorkbook()
        // 获取sheet,并填充数据
        SXSSFSheet sheet = wb.createSheet("mySheet")
        // 设置导出头,略
        buildPoolSheetHeader(wb, sheet, args)
        // 设置当前页1\2,
        int countPageIndex = (int) Math.ceil(count / PERSON_MAX_SIZE)
        for (int i = 1; i <= countPageIndex; i++) {
            List<Map<String, Object>> dataList = getPersonPool(args, i)// 分页查询数据库
            // 填充sheet,略
            fillPoolSheet(wb, sheet, fillList, dataList, i)
        }
        return wb
    }

    /**
     * 小数据量
     */
    XSSFWorkbook exportPersonPoolSmall(@Nullable Object... args) {
        XSSFWorkbook wb = new XSSFWorkbook()
        // 获取sheet,并填充数据
        XSSFSheet sheet = wb.createSheet("mySheet")
        // 设置导出头,略
        buildPoolSheetHeader(wb, sheet, args)
        List<Map<String, Object>> dataList = getPersonPool(args,1)// 查询数据库(第一页)
        // 填充sheet,略
        fillPoolSheet(wb, sheet, fillList, dataList, 1)

        return wb
    }

	 /**
	  * 填充sheet
	  */
	private void fillPoolSheet(@Nullable Object... args) {
		// 略
	
	
		if (sheet instanceof SXSSFWorkbook) {
	        ((SXSSFSheet) sheet).flushRows()
	    }
	}


上文路径:工具类——Java 浏览器导入、导出Excel(Java import、export)
如何生成临时文件,参考:导出/service后半段
如何浏览器下载,参考:导出/controller后半段

为脱敏手改代码,可能存在错误,还请与我交流,谢谢!文章来源地址https://www.toymoban.com/news/detail-427358.html

到了这里,关于工具类——Java导出EXCEL2(设置样式、加载并填充图片、加载指定模板、大数据量设置窗口大小与刷新频率)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用easyexcel填充模板数据,并导出excel

    导出excel功能非常场景,本片文章记录如何使用模板填充数据后再导出。因直接导出excel数据样式不符合要求,所以做了模板填充然后再导出excel。 效果如下: 注意:列表数据变量名前面要写点{.id},如果单条数据可以不写。 使用表单提交: 实体代码: controller代码: 只对je

    2024年03月11日
    浏览(52)
  • easyexcel根据模板导出Excel文件,表格自动填充问题

    同事在做easyexcel导出Excel,根据模板导出的时候,发现导出的表格,总会覆盖落款的内容。 这就很尴尬了,表格居然不能自动填充,直接怒喷工具,哈哈。 然后一起看了一下这个问题。 我找了自己的系统中关于表格导出的页面,导出了一下,发现可以正常扩充。 于是排查问

    2024年02月06日
    浏览(47)
  • Java 操作 Excel:生成数据、设置单元格样式、设置数据有效性(hutool)

    该篇文章,主要通过 Java 代码对 Excel 文件的常用操作,包括:生成表格、修改单元格样式、设置数据有效性。 该篇文章,在官网文献下增加个人的看法和理解,如文中有出现不符、错误或需要补充的地方,欢迎指正,非常感谢。 该篇文章操作 Excel 使用了 hutool 的工具包以及

    2024年02月04日
    浏览(38)
  • Java使用poi导出excel针对不同数据列配置设置不同单元格格式(适用于通用导出excel数据)

    公司大部分业务都是查询相关的业务, 所以建了一个项目专门做数据查询, 数据中转等抽象通用的业务, 有一天给我安排了一个功能, 做excel导出, 配置好查询sql和表头字段映射后即可导出excel, 无需修改代码 后来因为导出数据要求保留几位小数或者转换成百分比等设置单元格格

    2024年02月07日
    浏览(55)
  • Java中使用JXLS工具类导出复杂Excel表格

    前言    在项目开发中,我们会遇到各种文件导出的开发场景,但是这种情况并都不常用,于是本人将自己工作中所用的代码封装成工具类,旨在记录工具类使用方法和技术分享。 一、Jxls的简介    Jxls是一个简单的、轻量级的excel导出库,使用特定的标记在excel模板文件中来

    2024年02月03日
    浏览(48)
  • java poi导出excel单元格设置自定义背景颜色(任意颜色)

    一、思考过程(看代码的移步第二点) 现有方法 现有资料多为使用 IndexedColors 设置颜色, 但是IndexedColors能设置的颜色有限 ,而需求中所要颜色都是花里胡哨的,需要真正的自定义; 而颜色的本质是rgb ,所以只要我们能自己设置rgb的值就能获取任意想要的颜色了; 源码分

    2023年04月10日
    浏览(43)
  • Java 使用hutool工具进行导出导入excel表格(代码很简单)

    创建一个Controller进行测试 

    2024年02月07日
    浏览(65)
  • 使用Java导入、导出excel详解(附有封装好的工具类)

    😜 作           者 :是江迪呀 ✒️ 本文 : Java 、 Excel 、 导出 、 工具类 、 后端 ☀️ 每日   一言 :有些事情不是对的才去坚持,而是坚持了它才是对的! 我们在日常开发中,一定遇到过要将数据导出为 Excel 的需求,那么怎么做呢?在做之前,我们需要思考

    2024年02月06日
    浏览(51)
  • java-EasyExcel导出excel设置单元格为文本格式(含代码)

    java-EasyExcel导出excel设置单元格为文本格式(含代码) 在使用EasyExcel导出excel模板时。我们会发现导出的日期和大长度数字都会自动更换格式,不是文本格式。并且在空白单元格输入日期也是格式有问题的,如下所示,可以看到当输入相同的日期时,格式会变成自适应,不是文

    2023年04月15日
    浏览(47)
  • 使用EasyPoi实现Excel的按模板样式导出

    1690342020350导出测试.xlsx 如下 #fe 使用#fe命令可以实现集合数据的横向拓展,比如模板代码是 导出的excel里面就会显示会自当前列,向右拓展,效果可参见下面的导出文件截图 v_fe 使用v_fe命令可以实现不固定列的横向遍历,比如模板代码是 分数 ID {{#fe:maths t.score t.id}} 这种情况

    2024年02月15日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包