Java excel导入/导出导致内存溢出问题,以及解决方案

news2025/4/17 8:08:21

excel导入/导出导致内存溢出问题,以及解决方案

  • 1、内存溢出问题
    • 导入功能重新修正,采用SAX的流式解析数据。并结合业务流程。
    • 导出功能:由于精细化了业务流程,导致比较代码比较冗杂,就只放出最简单的案例。

1、内存溢出问题

在这里插入图片描述
dump日志查看
org.apache.xmlbeans.impl.store.Xobj$AttrXob,占用了大量的内存
在这里插入图片描述
在这里插入图片描述

模拟复现
在这里插入图片描述
原因查明 XSSF对excel内容的完全占用不释放导致内存溢出,无论导入还是导出都是一样的原理。

导入功能重新修正,采用SAX的流式解析数据。并结合业务流程。

难点应该在对不同类型数据的处理。这需要使用到StylesTable styles;对数据格式进行处理。例如时间,浮点
excel数据是 分别是
文本日期, 日期,
文本数字,浮点数字,
数字,文本,
公式=A4+1,文本浮点

在这里插入图片描述
最终导出结果 符合预期
在这里插入图片描述

package com.bookm.service.excel3;

import com.alibaba.fastjson.JSONObject;
import com.bookm.bean.ImportColumnInfo;
import com.bookm.bean.ImportStatusDTO;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * 数据处理
 */
public class SheetHandler extends DefaultHandler {
    private SharedStringsTable sst;
    private StylesTable styles;
    private String lastContents;
    private boolean nextIsString;
    private String cellPosition;
    private int cellStyleIndex = -1;
    private LinkedHashMap<String, JSONObject> rowContents = new LinkedHashMap();
    private HashMap<String, ImportColumnInfo> icHash = new HashMap<>();
    private HashMap<String, String> columnMap = new HashMap<>();
    private DataFormatter dataFormatter = new DataFormatter();
    protected ImportStatusDTO imp_status = new ImportStatusDTO();

    public SheetHandler(SharedStringsTable sst, StylesTable styles) {
        this.sst = sst;
        this.styles = styles;
        setImportColumn(icHash);
    }

    public LinkedHashMap<String, JSONObject> getRowContents() {
        return rowContents;
    }

    public void setRowContents(LinkedHashMap<String, JSONObject> rowContents) {
        this.rowContents = rowContents;
        setImportColumn(icHash);
    }

    public SheetHandler(SharedStringsTable sst) {
        this.sst = sst;
        setImportColumn(icHash);
    }
    // 其他方法如setImportColumn、isExistProperty、isExistColumn保持不变

    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
        if (name.equals("c")) {
            cellPosition = attributes.getValue("r");
            String cellType = attributes.getValue("t");
            String cellStyleStr = attributes.getValue("s");
            //日期类型 cellType=null,cellStyleStr=4
            //文本 数字/浮点类型 cellType=s,cellStyleStr=1
            //浮点/数字类型 cellType=null,cellStyleStr=3
            //公式类型 cellType=null,cellStyleStr=null
            cellStyleIndex = cellStyleStr != null ? Integer.parseInt(cellStyleStr) : -1;
            nextIsString = "s".equals(cellType);
        }
        lastContents = "";
    }

    public void endElement(String uri, String localName, String name) throws SAXException {
        if (name.equals("v")) {
            String value = lastContents.trim();
            if (nextIsString) {
                try {
                    int idx = Integer.parseInt(value);
                    value = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
                } catch (NumberFormatException e) {
                    // 保持原值
                }
            } else {
                if (styles != null && cellStyleIndex != -1) {
                    try {
                        CellStyle style = styles.getStyleAt(cellStyleIndex);
                        short formatIndex = style.getDataFormat();
                        String formatString = style.getDataFormatString();
                        double numericValue = Double.parseDouble(value);

                        if (DateUtil.isADateFormat(formatIndex, formatString)) {
                            if (DateUtil.isValidExcelDate(numericValue)) {
                                Date date = DateUtil.getJavaDate(numericValue, false);
                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                                value = sdf.format(date);
                            }
                        } else {
                            value = dataFormatter.formatRawCellContents(numericValue, formatIndex, formatString);
                        }
                    } catch (NumberFormatException e) {
                        // 非数值,保持原样
                    }
                }
            }

            // 处理列映射和数据存储
            String positionAlpha = cellPosition.replaceAll("[0-9]", "").trim();
            String positionNum = cellPosition.replaceAll("[^0-9]", "").trim();

            if ("1".equals(positionNum)) {
                if (!isExistProperty(value, icHash)) {
                    imp_status.imp_rows_nomatch += value + ",";
                }
                for (String key : icHash.keySet()) {
                    ImportColumnInfo ic = icHash.get(key);
                    if (ic.ici_xls_title.equalsIgnoreCase(value)) {
                        columnMap.put(positionAlpha, ic.ici_column);
                        break;
                    }
                }
            } else if (isExistColumn(positionAlpha, columnMap)) {
                JSONObject rowData = rowContents.getOrDefault(positionNum, new JSONObject());
                rowData.put(columnMap.get(positionAlpha), value);
                rowContents.put(positionNum, rowData);
            }
        }
    }

    public void characters(char[] ch, int start, int length) {
        lastContents += new String(ch, start, length);
    }

    /**
     * 当前的列信息,是否在配置表内
     *
     * @param clm
     * @param iciHash
     * @return
     */
    protected boolean isExistColumn(String clm, HashMap<String, String> iciHash) {
        return iciHash.get(clm) == null ? false : true;
    }

    /**
     * 当前的第一行的名称是否在我的配置表里面 name : name
     *
     * @param clm
     * @param iciHash
     * @return
     */
    protected boolean isExistProperty(String clm, HashMap<String, ImportColumnInfo> iciHash) {
        for (String key : iciHash.keySet()) {
            ImportColumnInfo ic = iciHash.get(key);
            if (ic.ici_xls_title.equalsIgnoreCase(clm)) {
                return true;
            }
        }
        return false;
    }

    // todo 为了结合过去的接口 ,创建handler必须实现这个接口
    void setImportColumn(HashMap<String, ImportColumnInfo> icHash) {
        icHash = new HashMap<>();
        ImportColumnInfo impinfo = null;
//		List<GenColumn> genColumnList = getGenColumnByTabName(tableName);
        impinfo = new ImportColumnInfo();
        impinfo.ici_column = "type";
        impinfo.ici_xls_title = "type";
        impinfo.ici_xls_type = "String";
        icHash.put(impinfo.ici_column, impinfo);

        impinfo = new ImportColumnInfo();
        impinfo.ici_column = "name";
        impinfo.ici_xls_title = "name";
        impinfo.ici_xls_type = "String";
        icHash.put(impinfo.ici_column, impinfo);
        this.icHash = icHash;
    }
}
package com.bookm.service.excel3;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.bookm.bean.Book;
import com.bookm.bean.ImportColumnInfo;
import com.bookm.service.excel2.SheetHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 数据量比较大(8万条以上)的excel文件解析,将excel文件解析为 行列坐标-值的形式存入map中,此方式速度快,内存耗损小 但只能读取excel文件
 * 提供处理单个sheet方法 processOneSheet(String  filename) 以及处理多个sheet方法 processAllSheets(String  filename)
 * 只需传入文件路径+文件名即可  调用处理方法结束后,只需接收ExcelUtil.getRowContents()返回值即可获得解析后的数据
 */
public class ExcelUtil {
    private static LinkedHashMap<String, JSONObject> rowContents = new LinkedHashMap<String, JSONObject>();
    public static SheetHandler sheetHandler;

    public LinkedHashMap<String, JSONObject> getRowContents() {
        return rowContents;
    }

    public static void setRowContents(LinkedHashMap<String, JSONObject> rc) {
        rowContents = rc;
    }

    public SheetHandler getSheetHandler() {
        return sheetHandler;
    }

    public static void setSheetHandler(SheetHandler sh) {
        sheetHandler = sh;
    }

    public static List<LinkedHashMap<String, JSONObject>> processSheetByRId(InputStream in, Integer count) throws Exception {
        OPCPackage pkg = null;
        InputStream sheet = null;
        List<LinkedHashMap<String, JSONObject>> results = new ArrayList<>();
        try {
            pkg = OPCPackage.open(in);
            XSSFReader r = new XSSFReader(pkg);
            SharedStringsTable sst = r.getSharedStringsTable();
            StylesTable stylesTable = r.getStylesTable();
            for (int i = 0; i < count; i++) {
                sheet = r.getSheet("rId" + (i + 1));
                InputSource sheetSource = new InputSource(sheet);
                HashMap<String, ImportColumnInfo> stringImportColumnInfoHashMap = setImportColumn(new HashMap<>());
                XMLReader parser = fetchSheetParser(sst, stylesTable, stringImportColumnInfoHashMap);
                parser.parse(sheetSource);
                results.add(sheetHandler.getRowContents());
            }

            return results;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (pkg != null) {
                pkg.close();
            }
            if (sheet != null) {
                sheet.close();
            }
        }
    }


    // 处理一个sheet
    public static void processOneSheet(String filename) throws Exception {
        InputStream sheet2 = null;
        OPCPackage pkg = null;
        try {
            pkg = OPCPackage.open(filename);
            XSSFReader r = new XSSFReader(pkg);
            SharedStringsTable sst = r.getSharedStringsTable();
            StylesTable stylesTable = r.getStylesTable();
            HashMap<String, ImportColumnInfo> stringImportColumnInfoHashMap = setImportColumn(new HashMap<>());
            XMLReader parser = fetchSheetParser(sst, stylesTable, stringImportColumnInfoHashMap);
            sheet2 = r.getSheet("rId1");
            InputSource sheetSource = new InputSource(sheet2);
            parser.parse(sheetSource);
            setRowContents(sheetHandler.getRowContents());
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (pkg != null) {
                pkg.close();
            }
            if (sheet2 != null) {
                sheet2.close();
            }
        }
    }

    // 处理多个sheet
    public static void processAllSheets(String filename) throws Exception {
        OPCPackage pkg = null;
        InputStream sheet = null;
        try {
            pkg = OPCPackage.open(filename);
            XSSFReader r = new XSSFReader(pkg);
            SharedStringsTable sst = r.getSharedStringsTable();
            StylesTable stylesTable = r.getStylesTable();
            setImportColumn(new HashMap<>());
            HashMap<String, ImportColumnInfo> stringImportColumnInfoHashMap = setImportColumn(new HashMap<>());
            XMLReader parser = fetchSheetParser(sst, stylesTable, stringImportColumnInfoHashMap);
            Iterator<InputStream> sheets = r.getSheetsData();
            while (sheets.hasNext()) {
                System.out.println("Processing new sheet:\n");
                sheet = sheets.next();
                InputSource sheetSource = new InputSource(sheet);
                parser.parse(sheetSource);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (pkg != null) {
                pkg.close();
            }
            if (sheet != null) {
                sheet.close();
            }
        }
    }


    public static XMLReader fetchSheetParser(SharedStringsTable sst, StylesTable sharedStringsTable, HashMap importNeedColumnMap) throws SAXException {
        XMLReader parser = XMLReaderFactory.createXMLReader("com.sun.org.apache.xerces.internal.parsers.SAXParser");
        final SheetHandler sheetHandler = new SheetHandler(sst, sharedStringsTable);
        sheetHandler.importNeedColumnMap = importNeedColumnMap;
        setSheetHandler(sheetHandler);
        ContentHandler handler = (ContentHandler) sheetHandler;
        parser.setContentHandler(handler);
        return parser;
    }

    static HashMap<String, ImportColumnInfo> setImportColumn(HashMap<String, ImportColumnInfo> icHash) {
        icHash = new HashMap<>();
        ImportColumnInfo impinfo = null;
//		List<GenColumn> genColumnList = getGenColumnByTabName(tableName);
        impinfo = new ImportColumnInfo();
        impinfo.ici_column = "type";
        impinfo.ici_xls_title = "type";
        impinfo.ici_xls_type = "String";
        icHash.put(impinfo.ici_column, impinfo);

        impinfo = new ImportColumnInfo();
        impinfo.ici_column = "name";
        impinfo.ici_xls_title = "name";
        impinfo.ici_xls_type = "String";
        icHash.put(impinfo.ici_column, impinfo);
        return icHash;
    }

    /**
     * See org.xml.sax.helpers.DefaultHandler
     */
    public static void main(String[] args) throws Exception {
//        test();
        test2();
    }

    public static void test() throws Exception {
        ExcelUtil example = new ExcelUtil();
        example.processOneSheet("data.xlsx");

        LinkedHashMap<String, JSONObject> map = example.getRowContents();

        ObjectMapper mapper = new ObjectMapper();
        List<Book> books = map.values().stream().parallel()
                .map(jsonObject -> {
                    try {
                        return mapper.readValue(jsonObject.toString(), Book.class);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                })
                .collect(Collectors.toList());
        books.forEach(item -> System.out.println(item));

    }

    public static void test2() throws Exception {
        ExcelUtil example = new ExcelUtil();
        final List<LinkedHashMap<String, JSONObject>> linkedHashMaps = example.processSheetByRId(new FileInputStream(new File("data.xlsx")), 2);
        linkedHashMaps.forEach(item->{
            System.out.println(item);
        });
    }
}


导出功能:由于精细化了业务流程,导致比较代码比较冗杂,就只放出最简单的案例。

package com.bookm;

import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.FileOutputStream;
import java.io.OutputStream;

@SpringBootTest
public class ExportTest {


    /**
     * SXSSFWorkbook : 100w条数据写入Excel 消耗时间:8706
     */
    @Test
    public void test1() {
        try {
            long t1 = System.currentTimeMillis();
            SXSSFWorkbook workbook = new SXSSFWorkbook();
            workbook.createSheet("aaa");
            SXSSFSheet aaa = workbook.getSheetAt(0);
            for (int i = 0; i < 1000000; i++) {
                aaa.createRow(i);
                aaa.getRow(i).createCell(0).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
                aaa.getRow(i).createCell(1).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
                aaa.getRow(i).createCell(2).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
                aaa.getRow(i).createCell(3).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
                aaa.getRow(i).createCell(4).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
            }
            OutputStream outputStream = null;
            // 打开目的输入流,不存在则会创建
            outputStream = new FileOutputStream("out.xlsx");
            workbook.write(outputStream);
            outputStream.close();
            long t2 = System.currentTimeMillis();
            System.out.println("SXSSFWorkbook : 100w条数据写入Excel 消耗时间:" + (t2 - t1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * SXSSFWorkbook : 1w条数据写入Excel 消耗时间:2151
     * SXSSFWorkbook : 100w条数据写入Excel 消耗时间:215100,  如果说组织分配
     */
    @Test
    public void test2() {

        try {
            long t1 = System.currentTimeMillis();
            XSSFWorkbook workbook = new XSSFWorkbook();
            workbook.createSheet("aaa");
            XSSFSheet aaa = workbook.getSheetAt(0);
            for (int i = 0; i < 10000; i++) {
                aaa.createRow(i);
                aaa.getRow(i).createCell(0).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
                aaa.getRow(i).createCell(1).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
                aaa.getRow(i).createCell(2).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
                aaa.getRow(i).createCell(3).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
                aaa.getRow(i).createCell(4).setCellValue("aaaaaaaaaaaaaaaaaaaaaaa");
            }
            OutputStream outputStream = null;
            // 打开目的输入流,不存在则会创建
            outputStream = new FileOutputStream("out2.xlsx");
            workbook.write(outputStream);
            outputStream.close();
            long t2 = System.currentTimeMillis();
            System.out.println("XSSFWorkbook : 100w条数据写入Excel 消耗时间:" + (t2 - t1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

引用: 感谢大佬们的付出
[1]: https://blog.csdn.net/u013803955/article/details/137792819

如果有需要练手,到时候有空再把代码传git吧
似乎代码仍然是不完全的。如果有需要再传吧

仓库地址
git@gitee.com:ssm785265/12.BookM_in_export_jvm.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2335526.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

10 个最新 CSS 功能已在所有主流浏览器中得到支持

前言 CSS 不断发展&#xff0c;新功能使我们的工作更快、更简洁、更强大。得益于最新的浏览器改进&#xff08;Baseline 2024&#xff09;&#xff0c;许多新功能现在可在所有主要引擎上使用。以下是您可以立即开始使用的10 CSS新功能。 1. Scrollbar-Gutter 和 Scrollbar-Co…

思科模拟器的单臂路由,交换机,路由器,路由器只要两个端口的话,连接三台电脑该怎么办,划分VLAN,dotlq协议

单臂路由 1. 需求&#xff1a;让三台电脑互通 2. 在二层交换机划分vlan&#xff0c;并加入&#xff1b; 3. 将连接二层交换机和路由器的端口f0/4改为trunk模式 4. 路由器&#xff1a;进入连接路由器的f0/0端口将端口开启 5. 进入每个vlan设dotlq协议并设网络IP&#xff08…

14 nginx 的 dns 缓存的流程

前言 这个是 2020年11月 记录的这个关于 nginx 的 dns 缓存的问题 docker 环境下面 前端A连到后端B 前端B连到后端A 最近从草稿箱发布这个问题的时候, 重新看了一下 发现该问题的记录中仅仅是 定位到了 nginx 这边的 dns 缓存的问题, 但是 并没有到细节, 没有到 具体的 n种…

实战教程:使用JetBrians Rider快速部署与调试PS5和Xbox上的UE项目

面向主机游戏开发者的重大新闻&#xff01;在2024.3版本中&#xff0c;JetBrains Rider 增加了对 PlayStation5 和 Xbox 游戏主机的支持&#xff0c;您可以直接在您喜欢的游戏主机上构建、部署和调试 Unreal Engine 和自定义游戏引擎。 JetBrains Rider现在支持主机游戏开发&am…

专题十五:动态路由——BGP

一、BGP的基本概念 BGP&#xff08;Border Gateway Protocol&#xff0c;边界网关协议&#xff09;是一种用于在不同自治系统&#xff08;AS&#xff09;之间交换路由信息的外部网关协议&#xff08;EGP&#xff09;。通过TCP179端口建立连接。目前采用BGP4版本&#xff0c;IP…

hive数仓要点总结

1.OLTP和OLAP区别 OLTP&#xff08;On-Line Transaction Processing&#xff09;即联机事务处理&#xff0c;也称为面向交易的处理过程&#xff0c;其基本特征是前台接收的用户数据可以立即传送到计算中心进行处理&#xff0c;并在很短的时间内给出处理结果&#xff0c;是对用…

git安装(windows)

通过网盘分享的文件&#xff1a;资料(1) 链接: https://pan.baidu.com/s/1MAenYzcQ436MlKbIYQidoQ 提取码: evu6 点击next 可修改安装路径 默认就行 一般从命令行调用&#xff0c;所以不用创建。 用vscode&#xff0c;所以这么选择。

微信小程序实战案例 - 餐馆点餐系统 阶段1 - 菜单浏览

阶段 1 – 菜单浏览&#xff08;超详细版&#xff09; 目标&#xff1a;完成「首页&#xff1d;菜品卡片列表」 打好 UI 地基会从 云数据库 拉取 categories / dishes 并渲染打 Git Tag v1.0‑menu 1. 技术/知识点速览 知识点关键词说明云数据库db.collection().where().…

Dashboard的安装和基本使用

1.Dashboard简介&#xff1a; Dashboard是Kubernetes的Web图形用户界面&#xff08;GUI&#xff09;&#xff0c;它为用户提供了一个直观的方式来管理和监控Kubernetes集群。 2.实验基础和前置条件&#xff1a; 本实验以Kubernetes集群环境搭建与初始化-CSDN博客为基础和前置…

英语单词 list 11

前言 这一个 list 是一些简单的单词。感觉这个浏览单词的方法比较低效&#xff0c;所以准备每天最多看一个 list &#xff0c;真要提升英语水平&#xff0c;感觉还是得直接做阅读理解题。就像我们接触中文阅读材料一样&#xff0c;当然光知道这个表面意思还不够&#xff0c;还…

通义灵码助力Neo4J开发:快速上手与智能编码技巧

在 Web 应用开发中&#xff0c;Neo4J 作为一种图数据库&#xff0c;用于存储节点及节点间的关系。当图结构复杂化时&#xff0c;关系型数据库的查找效率会显著降低&#xff0c;甚至无法有效查找&#xff0c;这时 Neo4J 的优势便凸显出来。然而&#xff0c;由于其独特的应用场景…

高性能文件上传服务

高性能文件上传服务 —— 您业务升级的不二选择 在当今互联网数据量激增、文件体积日益庞大的背景下&#xff0c;高效、稳定的文件上传方案显得尤为重要。我们的文件分块上传服务端采用业界领先的 Rust HTTP 框架 Hyperlane 开发&#xff0c;凭借其轻量级、低延时和高并发的特…

Java Lambda 表达式详解:发展史、语法、使用场景及代码示例

Java Lambda 表达式详解&#xff1a;发展史、语法、使用场景及代码示例 1. Lambda 表达式的发展史 背景与动机 JDK 7 前&#xff1a;Java的匿名内部类虽强大&#xff0c;但代码冗余&#xff08;如事件监听器、集合遍历&#xff09;。JDK 8&#xff08;2014&#xff09;&#…

【从0到1学Elasticsearch】Elasticsearch从入门到精通(下)

我们在【从0到1学Elasticsearch】Elasticsearch从入门到精通&#xff08;上&#xff09;这边文章详细讲解了如何创建索引库和文档及javaAPI操作&#xff0c;但是在实战当中&#xff0c;我们还需要根据一些特殊字段对文档进行查找搜索&#xff0c;仅仅靠id查找文档是显然不够的。…

Python实现贪吃蛇二

上篇文章Python实现贪吃蛇一&#xff0c;实现了一个贪吃蛇的基础版本&#xff0c;但存在一些不足&#xff0c;也缺乏一些乐趣。本篇文章将对其进行一些改进&#xff0c;主要修改/实现以下几点&#xff1a; 1、解决食物随机生成的位置与蛇身重合问题 2、蛇身移动加速/减速功能 3…

基于51单片机的正负5V数字电压表( proteus仿真+程序+设计报告+讲解视频)

基于51单片机的正负5V数字电压表( proteus仿真程序设计报告讲解视频&#xff09; 仿真图proteus7.8及以上 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;S0101 1. 主要功能&#xff1a; 设计一个基于51单片机数字电压表 1、能够…

Java雪花算法

以下是用Java实现的雪花算法代码示例&#xff0c;包含详细注释和异常处理&#xff1a; 代码下面有解析 public class SnowflakeIdGenerator {// 起始时间戳&#xff08;2020-01-01 00:00:00&#xff09;private static final long START_TIMESTAMP 1577836800000L;// 各部分…

前端大屏可视化项目 局部全屏(指定盒子全屏)

需求是这样的&#xff0c;我用的项目是vue admin 项目 现在需要在做大屏项目 不希望显示除了大屏的其他东西 于是想了这个办法 至于大屏适配问题 请看我文章 底部的代码直接复制就可以运行 vue2 px转rem 大屏适配方案 postcss-pxtorem-CSDN博客 <template><div …

01_JDBC

文章目录 一、概述1.1、什么是JDBC1.2、JDBC原理 二、JDBC入门2.1、准备工作2.1.1、建库建表2.1.2、新建项目 2.2、建立连接2.2.1、准备四大参数2.2.2、加载驱动2.2.3、准备SQL语句2.2.4、建立连接2.2.5、常见问题 2.3、获取发送SQL的对象2.4、执行SQL语句2.5、处理结果2.6、释…

Spring Boot 热部署详解,包含详细的配置项说明

Spring Boot 热部署详解 1. 热部署简介 热部署&#xff08;Hot Deployment&#xff09;允许在应用运行时修改代码或配置文件&#xff0c;无需重启应用即可使更改生效。Spring Boot 通过 spring-boot-devtools 模块实现这一功能&#xff0c;其核心依赖于 LiveReload 技术和自动…