java SXSSF 导出excel 合并单元格,设置打印分页

四、java基于poi源码操作excel之XSSFCell源码类 XSSFCell源码类 pom配置 <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </depend 阅读详情

官方poi地址:

Busy Developers' Guide to HSSF and XSSF Features

HSSFWorkbook、XSSFWorkbook、SXSSFWorkbook的区别:

◎HSSFWorkbook一般用于Excel2003版及更早版本(扩展名为.xls)的导出。

◎XSSFWorkbook一般用于Excel2007版(扩展名为.xlsx)的导出。

◎SXSSFWorkbook一般用于大数据量的导出。

    /**
     * 导出人事档案目录  组织数据
     * @param list
     * @param personnelIdToList
     * @param qtyMap
     */
    @Override
    public void exportCatalogue(String year,
                                List<TnPersonnel> list,
                                Map<String, List<TrPersonnelCatalogue>> personnelIdToList,
                                Map<String, Integer> qtyMap) {
        Map<String, String> headMap = new LinkedHashMap<String, String>();// 存放表头部信息
        headMap.put("index", "序号");
        headMap.put("name", "材料名称");
        headMap.put("year", "年");
        headMap.put("month", "月");
        headMap.put("day", "日");
        headMap.put("total", "页数");
        headMap.put("remarks", "备注");
        String zipBucketName = CommonConstants.BUCKET_NAME + year + "excel";
        sysFileService.createBucket(zipBucketName);
        String fileName = year + "excel/";
        File f = new File(CommonConstants.BUCKET_PATH + zipBucketName + "/"+ fileName);   //new的一个File对象
        //先删除之前的文件夹
        FileUtils.deleteQuietly(f);
        sysFileService.craertTreeFile(zipBucketName, fileName);
        for (TnPersonnel tnPersonnel : list) {
            String serialNumber = tnPersonnel.getSerialNumber();
            String name = tnPersonnel.getName();
            String id = tnPersonnel.getId();
            String title =  serialNumber + name + ".xlsx";
            String path = CommonConstants.BUCKET_PATH + zipBucketName + "/"+ fileName + title;

            try {
                JSONObject personnelJo = new JSONObject();
                JSONArray catalogueJa = new JSONArray();
                List<TrPersonnelCatalogue> trPersonnelCatalogues = personnelIdToList.get(id);
                //添加大分类-
                List<TrPersonnelCatalogue> newCata = this.creatTitle(trPersonnelCatalogues);
                for (int i = 0; i < newCata.size(); i++) {
                    JSONObject jo = new JSONObject();
                    TrPersonnelCatalogue personnelCatalogue = newCata.get(i);
                    String catalogueId = personnelCatalogue.getId();
                    String cataDate = personnelCatalogue.getCataDate();
                    String createYear = "";
                    String month = "";
                    String day = "";
                    if(StringUtils.isNotBlank(cataDate)){
                        Date date = DateUtils.parseDate(cataDate, "yyyy-MM-dd");
                        createYear = DateUtils.formatDate(date, "yyyy");
                        month = DateUtils.formatDate(date, "MM");
                        day = DateUtils.formatDate(date, "dd");
                    }
                    String dateType = personnelCatalogue.getDateType();
                    String no = personnelCatalogue.getNo();
                    jo.put("index", no);
                    jo.put("name", personnelCatalogue.getName());
                    jo.put("year", createYear);
                    if("0".equals(dateType) || "2".equals(dateType) ||StringUtils.isBlank(dateType)){
                        jo.put("month", month);
                    }
                    if("2".equals(dateType) || StringUtils.isBlank(dateType)){
                        jo.put("day", day);
                    }
                    jo.put("total", qtyMap.get(catalogueId));
                    jo.put("remarks", "");
                    catalogueJa.add(jo);
                }
                personnelJo.put("name", name);
                personnelJo.put("catalogueJa", catalogueJa);

                // 生成文件临时存放目录
                File destination = new File(path);
                File dir = destination.getParentFile();
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                if (!destination.exists()) {
                    destination.createNewFile();
                }
                OutputStream outXlsx = new FileOutputStream(destination);
                ExcleUtils.exportCatalogue(headMap, personnelJo, "yyyy-MM-dd", 6, outXlsx);
                outXlsx.close();
            } catch (Exception e) {
                System.out.println("导出异常");
                e.printStackTrace();
            }
        }
    }
/**
     * 导出人事档案目录  构建表头和页尾
     *
     * @param headMap  表头Map
     * @param personnelJo 表格内容
     * @param datePattern 日期格式
     * @param colWidth  列宽
     * @param out
     */
    public static void exportCatalogue(Map<String, String> headMap, JSONObject personnelJo,
                                       String datePattern, int colWidth, OutputStream out) {
        if (datePattern == null) datePattern = DEFAULT_DATE_PATTERN;
        // 声明一个工作薄
        SXSSFWorkbook workbook = new SXSSFWorkbook(1000);//缓存
        workbook.setCompressTempFiles(true);
        //加外框样式
        CellStyle borderstyle = workbook.createCellStyle();
        borderstyle.setBorderBottom(BorderStyle.THIN); //下边框
        borderstyle.setBorderLeft(BorderStyle.THIN);//左边框
        borderstyle.setBorderTop(BorderStyle.THIN);//上边框
        borderstyle.setBorderRight(BorderStyle.THIN);//右边框
        borderstyle.setAlignment(HorizontalAlignment.CENTER);//文字居中
        borderstyle.setWrapText(true);
        //居中样式
        CellStyle centerCellStyle = workbook.createCellStyle();
        centerCellStyle.setAlignment(HorizontalAlignment.CENTER);
        //设置列宽
        int minBytes = colWidth < DEFAULT_COLOUMN_WIDTH ? DEFAULT_COLOUMN_WIDTH : colWidth;//至少字节数
        int[] arrColWidth = new int[headMap.size()];
        // 产生表格标题行,以及设置列宽
        String[] properties = new String[headMap.size()];
        String[] headers = new String[headMap.size()];
        int ii = 0;
        // 生成一个表格
        SXSSFSheet sheet = workbook.createSheet();
        //默认列宽
        sheet.setDefaultColumnWidth(5000);
        for (Iterator<String> iter = headMap.keySet().iterator(); iter
                .hasNext(); ) {
            String fieldName = iter.next();
            properties[ii] = fieldName;
            headers[ii] = headMap.get(fieldName);
            ii++;
        }
        sheet.setColumnWidth(1, 8000);
        // 页边距(左)
        sheet.setMargin(SXSSFSheet.LeftMargin,( double ) 1 );
        //设置打印页面为水平居中
        sheet.setHorizontallyCenter(true);
        //TODO 在POI的api中没有找到打印页面的得到方式
//        Footer footer = sheet.getFooter();
//        footer.setCenter( "第" + HeaderFooter.page() + "页,共 " + HeaderFooter.numPages()+"页" );
//        footer.setCenter(sheet.);
        //循环人员

        Object name = personnelJo.get("name");
        JSONArray catalogueJa = (JSONArray) JSONObject.toJSON(personnelJo.get("catalogueJa"));
        //第一行,表名
        SXSSFRow oneRow = sheet.createRow(0); //列头 rowIndex =1
        SXSSFCell cell = oneRow.createCell(0);
        cell.setCellValue("人事档案目录");
        CellStyle cellStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setFontHeightInPoints((short) 15);
        font.setBold(true);
        cellStyle.setFont(font);
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cell.setCellStyle(cellStyle);
        //合并单元格
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.length - 1));
        //第二行,姓名
        SXSSFRow nameRow = sheet.createRow(1); //列头 rowIndex =1
        SXSSFCell nameCell = nameRow.createCell(0);
        nameCell.setCellValue("姓名:" + name);
        //合并单元格
        sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, headers.length - 1));
        //第三行,表头
        SXSSFRow headerOne = sheet.createRow(2); //列头 rowIndex =1
        SXSSFRow headerTwo = sheet.createRow(3); //列头 rowIndex =1
        for (int i = 0; i < headers.length; i++) {
            SXSSFCell cell1 = headerOne.createCell(i);
            cell1.setCellValue(headers[i]);
            SXSSFCell cell2 = headerTwo.createCell(i);
            cell2.setCellValue(headers[i]);
            cell1.setCellStyle(borderstyle);
            cell2.setCellStyle(borderstyle);
        }
        SXSSFCell dateCell = headerOne.createCell(2);
        dateCell.setCellValue("材料形成日期");
        dateCell.setCellStyle(borderstyle);
        sheet.addMergedRegion(new CellRangeAddress(2, 3, 0, 0));
        sheet.addMergedRegion(new CellRangeAddress(2, 3, 1, 1));
        sheet.addMergedRegion(new CellRangeAddress(2, 2, 2, 4));
        sheet.addMergedRegion(new CellRangeAddress(2, 3, 5, 5));
        sheet.addMergedRegion(new CellRangeAddress(2, 3, 6, 6));
        //生成表格内容
        updateCell(catalogueJa, sheet, properties,
                datePattern, borderstyle, headers, workbook, name, centerCellStyle);
        try {
            workbook.write(out);
            workbook.close();
//            boolean flag =  workbook.dispose();//释放磁盘空间。处理在磁盘上支持这个工作簿的临时文件。调用该方法将使工作簿不可用。
//            System.out.println(flag);//如果所有临时文件都被成功删除,则为真。
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  /**
     * @param catalogueJa, sheet, properties, datePattern, borderstyle
     * @return void
     * @Description :导出人事档案目录-生成表格内容
     * @author caohong
     * @date 2021/11/3
     */
    private static void updateCell(JSONArray catalogueJa,
                                   SXSSFSheet sheet, String[] properties,
                                   String datePattern, CellStyle borderstyle,
                                   String[] headers, SXSSFWorkbook workbook,
                                   Object name,CellStyle centerCellStyle) {
        // 遍历集合数据,产生数据行
        int rowIndex = 4;
        //记录打印时每页行数
        int printRow = 0;
        //记录打印时每页总行数
        int totalRow = 40;
        //页码
        int page = 1;
        ArrayList<String> noArr = creatTitle();
        for (Object object : catalogueJa) {
            JSONObject catalogueJo = (JSONObject) JSONObject.toJSON(object);
            SXSSFRow dataRow = sheet.createRow(rowIndex);
            for (int i = 0; i < properties.length; i++) {
                Object o = catalogueJo.get(properties[i]);
                String cellValue = "";
                if (o == null) cellValue = "";
                else if (o instanceof Date) cellValue = new SimpleDateFormat(datePattern).format(o);
                else if (o instanceof Float || o instanceof Double)
                    cellValue = new BigDecimal(o.toString()).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
                else cellValue = o.toString();

                if (i == 0 && noArr.indexOf(cellValue) > -1) {
                    if (printRow < totalRow) {
                        int j = totalRow - printRow;
                        //处理空行
                        for (int k = 1; k < j; k++) {
                            SXSSFRow dataRowBlank = sheet.createRow(rowIndex++);
                            for (int a = 0; a < properties.length; a++) {
                                if (k == 1) {
                                    SXSSFCell newCell = dataRow.createCell(a);
                                    //设置边框
                                    newCell.setCellStyle(borderstyle);
                                }
                                SXSSFCell newCell = dataRowBlank.createCell(a);
                                //设置边框
                                newCell.setCellStyle(borderstyle);
                            }
                        }
                    }
                    //页尾
                    SXSSFRow endRow = sheet.createRow(rowIndex);
                    SXSSFCell pgaeCell = endRow.createCell(0);
                    pgaeCell.setCellValue("第" + page + "页");
                    pgaeCell.setCellStyle(centerCellStyle);
                    //合并单元格
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, headers.length - 1));
                    rowIndex = rowIndex + 1;
                    //设置在特定行的添加分页符
                    sheet.setRowBreak(rowIndex - 1);
                    //添加分页符之后,重置打印行数
                    printRow = 0;
                    //第一行,表名
                    SXSSFRow oneRow = sheet.createRow(rowIndex); //列头 rowIndex =1
                    SXSSFCell cell = oneRow.createCell(0);
                    cell.setCellValue("人事档案目录");
                    CellStyle cellStyle = workbook.createCellStyle();
                    Font font = workbook.createFont();
                    font.setFontHeightInPoints((short) 15);
                    font.setBold(true);
                    cellStyle.setFont(font);
                    cellStyle.setAlignment(HorizontalAlignment.CENTER);
                    cell.setCellStyle(cellStyle);
                    //合并单元格
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, headers.length - 1));
                    //第二行,姓名
                    SXSSFRow nameRow = sheet.createRow(rowIndex + 1); //列头 rowIndex =1
                    SXSSFCell nameCell = nameRow.createCell(0);
                    nameCell.setCellValue("姓名:" + name);
                    //合并单元格
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 1, rowIndex + 1, 0, headers.length - 1));
                    //第三行,表头
                    SXSSFRow headerOne = sheet.createRow(rowIndex + 2); //列头
                    SXSSFRow headerTwo = sheet.createRow(rowIndex + 3); //列头
                    for (int b = 0; b < headers.length; b++) {
                        SXSSFCell cell1 = headerOne.createCell(b);
                        cell1.setCellValue(headers[b]);
                        SXSSFCell cell2 = headerTwo.createCell(b);
                        cell2.setCellValue(headers[b]);
                        cell1.setCellStyle(borderstyle);
                        cell2.setCellStyle(borderstyle);
                    }
                    SXSSFCell dateCell = headerOne.createCell(2);
                    dateCell.setCellValue("材料形成日期");
                    dateCell.setCellStyle(borderstyle);
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 0, 0));
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 1, 1));
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 2, 2, 4));
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 5, 5));
                    sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 6, 6));
                    //加表头行数
                    rowIndex = rowIndex + 4;
                    //生成
                    dataRow = sheet.createRow(rowIndex);
                    page++;
                }
                SXSSFCell newCell = dataRow.createCell(i);
                //填充内容
                newCell.setCellValue(cellValue);
                //设置边框
                newCell.setCellStyle(borderstyle);
            }
            rowIndex++;
            printRow++;
        }
        if (printRow < totalRow) {
            int j = totalRow - printRow;
            //处理空行
            for (int k = 1; k < j; k++) {
                SXSSFRow dataRowBlank = sheet.createRow(rowIndex);
                for (int a = 0; a < properties.length; a++) {
                    SXSSFCell newCell = dataRowBlank.createCell(a);
                    //设置边框
                    newCell.setCellStyle(borderstyle);
                }
                rowIndex++;
            }
        }
        //页尾
        SXSSFRow endRow = sheet.createRow(rowIndex);
        SXSSFCell pgaeCell = endRow.createCell(0);
        pgaeCell.setCellValue("第" + page + "页");
        pgaeCell.setCellStyle(centerCellStyle);
        //合并单元格
        sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, headers.length - 1));
        //取消excel默认的自动分页,打印时将excel文件打印在pdf的一页中。
        sheet.setAutobreaks(true);
    }
项目引用
<poi.version>3.17</poi.version>


        <!-- poi office -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-examples</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>${poi.version}</version>
        </dependency>

源码分析:ApacePOI之SXSSF 源码分析:Apace POI:SXSSF 背景 说明 在一次程序部署过程中,由于疏忽(计划使用非root用户启动),使用了root启动程序,程序执行成功。 当使用非root角色启动程序时-报错Caused by: java.io.IOException: 权限不够。 当发现这个错误时,怀疑是初次使用root角色启动程序,导致程序目录和文件权限被修改。 当第2次启动程序时,使用非root角色由于没有权限,导致无法正常执行。所以对整个程序目录进行重新赋权。但仍然报错。 只有使用root角色才可以执行成功。 最后 阅读详情

相关推荐

Java动态填充Excel模板:Apache POI实战与性能优化指南

在数据处理与报表生成领域,Excel模板动态填充是一项高频需求,它实现了样式与数据的关注点分离。其核心原理是通过程序化方式定位模板中的特定单元格或区域,并将业务数据精准注入,同时保持原有的复杂样式与格式。这项技术的核心价值在于大幅提升了报表开发的效率和可维护性,避免了手动重建样式的繁琐与错误。它广泛应用于财务对账、业务报表导出、数据批量打印等需要保持专业文档格式的场景。本文聚焦于使用Apache POI这一Java主流库,深入探讨如何高效实现模板读取、数据映射、样式继承等关键步骤,并针对“OutOfMemo

weixin_34101229的博客 305

SXSSFWork、SXSSFSheet使用总结

近期发现做的excel导出功能会导致内存溢出(推测),于是采用了SXSSFWork控制内存中存放的条数,搞了一个礼拜,碰到了许多问题,通过问题也对POI中的SXSSFWork有了深入的了解。在此做个总结。先上两个官方文档 官网POI中的介绍与实例 SXSSFWorkbook的API文档使用时注意一下几点: 1、SXSSF是限制滑动窗口中的行的访问来实现低内存的占用,注意是限制的是访问; 2、

V_Axis的博客 1万+

Java导出Excel实现左侧可折叠大纲:POI行分组实战与踩坑记录

在财务对账、项目管理、库存台账等业务场景中,Excel导出的数据往往具有天然的层级关系,用户希望像原生Excel分类汇总那样,通过左侧的加减号折叠或展开明细行。这种交互背后是Excel的行分组与大纲折叠机制,而Java开发者常借助Apache POI来编程实现。理解groupRow与setRowGroupCollapsed的底层原理,正确处理行号区间与嵌套层级,是导出带大纲Excel的关键。本文从行分组的核心概念出发,逐步讲解如何使用POI的SXSSFWorkbook递归写入树形数据,再统一生成分组区间,并

weixin_28713947的博客 213

使用POI中的SXSSFWorkbook做excel导出,并自定义模板导出

try {//新建工作簿//工作薄名称//设置每格数据的样式//垂直居中//水平居中//自动换行//字体大小ParamFontStyle.setFontName("宋体");//设置表头的样式//自动换行ParamFontStyle1.setFontName("黑体");//是否打开加粗//设置标题的样式//垂直居中//水平居中//自动换行ParamFontStyle2.setFontName("黑体");//设置标题的样式。

qq_49641620的博客 3133

基于树形结构与POI的Java多级表头Excel导出方案详解

在Java企业级应用开发中,数据导出是常见的功能需求,而Apache POI作为处理Office文档的核心库,其灵活性与复杂性并存。理解其底层原理,关键在于掌握如何将数据结构(如列表、树)映射到Excel的单元格与行列坐标上。这种映射能力对于实现动态、可配置的报表导出具有重要技术价值,尤其在需要展示复杂层级关系的业务场景中,如财务报表、绩效考核表等。通过构建树形结构模型来描述表头层级,并利用递归算法自动计算单元格的合并范围,可以将表头的定义与渲染逻辑解耦,从而提升代码的可维护性和扩展性。本文聚焦于利用POI

cuml0912的博客 567

Java中使用Apache POI实现Excel写入与打印完整指南

当我们谈论“Excel导出优化”时,表面上是在讲POI怎么用、内存怎么调,但实际上解决的是用户体验问题。一份排版整洁、数据准确、开箱即打的报表,能让业务人员少加班半小时;一套稳定高效的导出系统,能让运维半夜少接一个告警电话。而这,才是技术真正的价值所在。💡所以下次你在写的时候,不妨多想一步:这份文件最终会被谁看到?他需要用它做什么?也许正是这一点点共情,能让你写出更有温度的代码。❤️本文还有配套的精品资源,点击获取。

weixin_32047493的博客 960

XSSFWorkbook读取excel模版后写入的数据过多造成OOM,使用SXSSFWorkbook解决

最近在项目中遇到这样的场景,将一批json文件(上千个)数据转为list后,按照给定的excel模版格式,填充到模版中生成最终的excel文件。但是因为json文件过多,或者json文件中转为list后的数据量过大造成了oom异常:java.lang.OutOfMemoryError:Java heap space。 原因在于XSSFWorkbook创建的 book sheet row cell 等,此时是存在内存的并没有持久化,那么随着数据量增大内存的需求量也就增大,那么很大可能就是要 ...

FinelyYang的专栏 1万+

Web问卷统计结果导出Excel的实战方案

Excel导出是Web应用中高频但易被低估的关键能力,其本质是将结构化业务数据按OpenXML标准序列化为可交互的.xlsx文件。原理上需兼顾数据聚合、样式控制、流式写入与跨平台兼容性,技术价值在于保障导出文件在Excel、WPS、Numbers等主流工具中零报错打开、格式不崩、中文正常、支持筛选排序。典型应用场景包括用户调研、满意度分析、HR绩效统计等需交付给非技术人员的报表任务。本文聚焦问卷系统中‘统计结果→Excel’这一闭环,基于Apache POI SXSSF实现内存可控、样式预设、合并单元格安全

weixin_32306957的博客 262

Java操作Excel之POI:excel导出文件

开发步骤: * 1、创建一个工作簿 * 2、创建一个工作表 * 3、创建一个行对象 * 4、创建一个单元格对象,指定它的列 * 5、给单元格设置内容 ...

weixin_30809333的博客 155

深度强化学习中的动作屏蔽(Action Masking)

在复杂环境中使用动作屏蔽,实现更好的训练效果

Kiek17的博客 5877

Android 16(API 36)状态栏颜色适配全攻略:从沉浸式到自定义背景

本文全面解析Android 16(API 36)强制沉浸式状态栏带来的适配挑战,提供了从FrameLayout包裹法到动态修改Window背景色的核心解决方案。针对传统状态栏颜色设置失效问题,详细阐述了如何利用WindowInsets API实现自定义背景,并涵盖全屏模式、Fragment切换及第三方ROM兼容性等实战场景,为开发者提供一站式适配指南。

weixin_29227425的博客 596

Java POI多级表头Excel导出:树形模型、动态布局与SXSSF性能优化

在Java后端开发中,Excel报表导出是常见的业务需求,尤其涉及复杂表头结构时,如何高效、灵活地生成文件成为技术难点。Apache POI作为Java操作Office文档的核心库,其基础API提供了单元格与行的操作能力,但要实现动态、可维护的多级表头,需要深入理解其原理并进行架构设计。关键在于将业务表头抽象为树形数据结构,通过深度优先遍历算法自动计算单元格的合并范围与位置,从而将表头层级、跨列关系映射到Excel网格。这种设计不仅提升了代码的可复用性与可维护性,更能应对表头结构动态变化的场景,体现了高内聚

weixin_34075268的博客 383

STM32 使用IO口模拟I2C时序

上一篇《I2C协议详解》 我们了解了I2C的操作流程,这一篇,我们就使用I2C,来对EEPROM进行操作吧。 我们做两种选择: 1.时序由IO口模拟高低电平,需要了解协议并按照协议操作相应的IO口。 2.时序由硬件自行产生,不需要人工干预; 由硬件产生的I2C时序,我们借助Stm32Cube配置实现便可,我们这一篇,抛开Stm32Cube,手撕代码,根据I2C的时序,一步步地实现I2C对...

8937

EasyExcel实战:告别OOM,掌握Java高效Excel导入导出核心技巧

在Java后端开发中,处理Excel文件是常见的需求,但传统方式如Apache POI在处理大数据量时,常因DOM解析模型导致内存溢出(OOM)和性能瓶颈。其原理是将整个文件加载到内存,形成对象树,这在大数据场景下会引发内存爆炸和频繁的Full GC。为了解决这些问题,基于SAX事件模型的流式读写技术应运而生,它通过逐行解析和写入XML,将内存占用从与文件大小成正比降至与处理行宽成正比,从而在保证性能的同时显著降低内存压力。这项技术的核心价值在于能够高效、稳定地处理海量数据,适用于财务对账、报表生成、数据迁

weixin_33894640的博客 460

使用AI编写测试用例——详细教程

现阶段AI还不能完全替代人工测试用例编写,但如果把AI当做一个提高效率的工具,它将会是一个很强大的辅助。

公众号|软件测试老吴 3万+

Gemma 4 12B QAT+MTP小显存部署实战指南

大语言模型本地部署的核心瓶颈在于显存与推理效率的平衡。量化感知训练(QAT)通过在训练阶段模拟低精度计算,显著提升模型对INT4量化的鲁棒性;多令牌预测(MTP)则通过并行解码优化KV Cache复用,降低GPU kernel调用频次。二者协同可在8GB显存设备上稳定运行12B级模型,兼顾精度、速度与上下文长度。该方案适用于开发者本地AI助手、技术文档生成、SQL翻译等轻量但高交互需求场景,是当前Windows环境中小显存高效落地Gemma系列模型的工程最优解。

weixin_30934229的博客 377

Apache POI 操作Excel常用方法

Apache POI是一个流行的API,允许程序员使用Java程序创建,修改和显示MS Office文件。它是由Apache软件基金会开发和分发的开源库,用于使用Java程序设计或修改Microsoft Office文件。

weixin_49832841的博客 8598

【Claude Code】Extra inputs are not permitted 报错:代理网关剥离 Beta 标头的修复

通过代理或 LLM 网关连接 Anthropic API 时,Claude Code 报 "Extra inputs are not permitted"?根因是中间件删除了 anthropic-beta 请求标头,导致 Beta 字段被 API 拒绝。本文详解标头转发配置和 CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS 回退方案。

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 126

Freemarker模板导出复杂Excel:告别POI硬编码的高效方案

在Java报表开发中,复杂Excel导出常常意味着海量样式代码和合并单元格的反复调试。模板引擎Freemarker为这一场景提供了另一种思路:利用Excel原生支持的XML Spreadsheet 2003交换格式,将静态样式与动态数据分离,通过模板占位符和循环指令快速生成可被Excel识别的文件。相比POI逐行绘制单元格,该方案在表头复杂、样式固定、数据按模板填充的场景下,大幅降低开发和维护成本。同时结合HTML表格伪装方案与POI的边界对比,本文详解了模板制作、动态行号处理、公式渲染、多Sheet循环及

weixin_33857230的博客 257

【目标跟踪】多目标跟踪的评价工具motmetrics怎么使用?

多目标跟踪,通过motmetrics测试评价对应的视频。

聿默的博客 5369

python 实现一个完整的基于Python的多视角三维重建系统,包含特征提取与匹配、相机位姿估计、三维重建、优化和可视化等功能

本文介绍了一个基于Python的多视角三维重建系统的实现,涵盖了特征提取与匹配、相机位姿估计、三维重建、优化和可视化等功能。首先,系统通过安装必要的库(如OpenCV、NumPy等)并加载图像数据,初始化相机参数。接着,系统使用SIFT、SURF或ORB算法提取图像特征点,并通过FLANN或BF方法进行特征匹配,应用Lowe's ratio test筛选优质匹配。该系统为后续的相机位姿估计和三维重建奠定了基础,能够从多视角图像中恢复三维场景结构。

huanghm88的专栏 618

Java精确控制Excel打印页边距:POI单位换算与SXSSF实战

Excel自动化导出中,打印排版与屏幕显示分属两套独立体系,页面边距、纸张方向等参数存储于工作表级XML节点。Apache POI作为Java操作Excel的主流库,通过Sheet.setMargin控制边距时,须将厘米换算为英寸(ECMA-376规范),否则极易出现打印偏移。但仅设置边距不足以得到稳定输出,还需配合打印区域、缩放比例、重复表头等要素。批量报表场景下,SXSSF流式导出的临时文件与底层XSSFWorkbook存在同步盲区,可能导致边距丢失,需在写流前统一收口打印参数。理解这些原理,能帮助开发

weixin_33290540的博客 232

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

POi 常见读写Excel 及格式设置

目前常见读写Excel的工具类开源javaAPI有两种方式, 一个是JXL(Java Excel API) 官网地址:http://jexcelapi.sourceforge.net/ 一个是Apache的POI(Poor Obfuscation Implementation)官网地址:http://poi.apache.org/   POI支持微软的OLE2格式文件Office 2003...

5373

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Apache POI学习和使用

Apache POI软件简介模块Maven依赖官方文档EXCEL封装常用代码块1.1 常用代码块1.1.1 标题样式 通常设置样式1.1.2 内容通常设置样式1.1.3 下载导出excel代码片段1.1.4 excel导入1.5.1.1 数据有效性校验POI API教程1.4.1.1 如何创建一个WorkBook?1.4.1.2 如何创建一个Sheet?1.4.1.3 如何创建一个单元格?1.4.1.4 如何创建一个日期类型的单元格?1.4.1.5 创建多种格式的单元格1.4.1.6 Files 和Inpu

bellus 3326

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

POI操作Excel常用方法总结

目前常见读写Excel的工具类开源javaAPI有两种方式, 一个是JXL(Java Excel API) 官网地址:http://jexcelapi.sourceforge.net/ 一个是Apache的POI(Poor Obfuscation Implementation)官网地址:http://poi.apache.org/ POI支持微软的OLE2格式文件Office 2003及

wuyou1336的博客 4526

poi 打印格式代码设置

偷个懒,直接上代码吧,大家每一行我都写注释了的,更具需求可以自己设计自己的表格  @Action(value="outProductAction_print") public String print() throws Exception{ //HSSF 2003版 , XSSF 2007 版,07可以加载03,但03加载不来07 SXSSF ...

845
上一篇: Openresty Redis正确使用连接池(set_keepalive)
下一篇: 两个多选框(select)之间值的左右上下移动
ole_triangle_java
博客等级 码龄10年 82粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值