SpringBoot操作Excel实现导入和导出功能(详细讲解+Gitee源码)

news2025/1/20 3:47:07

前言:在日常的开发中,避免不了操作Excel,比如从系统当中导出一个报表,或者通过解析客户上传的Excel文件进行批量解析数据入库等等,本篇博客主要汇总日常开发中如何使用开源的Apache提供的POI流操作Excel进行导入导出功能详解。

目录

一、导入pom.xml依赖

二、准备数据

三、导出功能 

1、新建文件

2、新建工作簿

3、自定义样式

4、创建行和列并填充数据

5、合并单元格 

6、创建批注 

7、遍历数据

8、设置响应下载

9、运行截图

四、导入功能

1、获取单元格值方法

2、获取文件流

3、获取Excel文件对象

4、获取工作簿

5、获取首尾行下标

6、读取数据 

7、测试运行

五、完整代码

六、Gitee源码  


一、导入pom.xml依赖

这边我使用的是Apache提供的POI流来操作Excel。 

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- apache工具操作poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

二、准备数据

1、学生实体类

@Data
public class Student {

    private int id;

    private String name;

    private String sex;

    private String address;

    private String phone;
}

2、初始化数据

    public List<Student> initData(){
        List<Student> list = new ArrayList<>();
        Student student = new Student();
        student.setId(1);
        student.setName("张三");
        student.setSex("男");
        student.setAddress("江苏");
        student.setPhone("19991198111");
        list.add(student);
        student = new Student();
        student.setId(2);
        student.setName("李四");
        student.setSex("女");
        student.setAddress("南京");
        student.setPhone("1887119121");
        list.add(student);
        return list;
    }

    public void export(HttpServletResponse response) throws IOException {

        //获取学生数据
        List<Student> students = initData();
        //获取标题
        String[] titles = {"编号","姓名","性别","地址","电话"};
         
        //导出Excel的代码
        ...

    }

三、导出功能 

这边主要讲解关于遍历数据、设置单元格样式、合并单元格和插入批注一些常用的功能。

1、新建文件

这边提供了2种Excel格式的文件,选一个即可,为了更好的兼容性,这边我采用的是.xls格式。

//.xls格式
HSSFWorkbook workbook = new HSSFWorkbook();
//.xlsx格式
//XSSFWorkbook workbook = new XSSFWorkbook();

2、新建工作簿

这行代码就是新建一个名为学生表的工作簿

HSSFSheet sheet = workbook.createSheet("学生表");

3、自定义样式

实例化出来的cellStyle提供给了我们很多关于设置样式的方法,这边我就提供一些常用的设置单元格样式的代码,把它封装成了一个方法,每行代码上面都有注释。

HSSFCellStyle cellStyle = workbook.createCellStyle();

常用样式代码:

/**
     * 单元格样式
     * @param workbook
     * @param fontBold 是否加粗
     * @param isBorder 是否带边框
     * @param horizontalAlignment 水平对齐格式
     * @param verticalAlignment 垂直对齐格式
     * @return
     */
    private HSSFCellStyle getColumnStyle(HSSFWorkbook workbook,
                                         boolean fontBold,
                                         boolean isBorder,
                                         HorizontalAlignment horizontalAlignment,
                                         VerticalAlignment verticalAlignment) {
        // 设置字体
        HSSFFont font = workbook.createFont();
        //设置字体大小
        font.setFontHeightInPoints((short) 12);
        //设置字体名字
        font.setFontName("宋体");
        font.setBold(fontBold);
        //设置样式;
        HSSFCellStyle style = workbook.createCellStyle();
        // 是设置前景色不是背景色
        style.setFillForegroundColor(IndexedColors.RED.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        if (isBorder) {
            //设置底边框;
            style.setBorderBottom(BorderStyle.THIN);
            //设置底边框颜色;
            style.setBottomBorderColor(IndexedColors.BLACK.index);
            //设置左边框;
            style.setBorderLeft(BorderStyle.THIN);
            //设置左边框颜色;
            style.setLeftBorderColor(IndexedColors.BLACK.index);
            //设置右边框;
            style.setBorderRight(BorderStyle.THIN);
            //设置右边框颜色;
            style.setRightBorderColor(IndexedColors.BLACK.index);
            //设置顶边框;
            style.setBorderTop(BorderStyle.THIN);
            //设置顶边框颜色;
            style.setTopBorderColor(IndexedColors.BLACK.index);
        }
        //在样式用应用设置的字体;
        style.setFont(font);
        //设置自动换行;
        style.setWrapText(false);
        //设置水平对齐的样式为居中对齐;
        style.setAlignment(horizontalAlignment);
        //设置垂直对齐的样式为居中对齐;
        style.setVerticalAlignment(verticalAlignment);
        return style;
    }

4、创建行和列并填充数据

首先我们需要先通过HSSFRow创建单元行,其次再通过HSSFRow实例化的对象去创建单元列,最后通过HSSFCell实例化的对象去填充数据,这边我创建了一个名为学生信息表的标题。

//创建单元行
HSSFRow header = sheet.createRow(0);
//创建单元列
HSSFCell headerCell = header.createCell(0);
//填充信息
headerCell.setCellValue("学生信息表");

再通过同样的代码遍历我们的字段标题

//创建第一行
HSSFRow titleRow = sheet.createRow(1);

//写入标题
for(int i = 0 ; i < titles.length ; i++ ){
HSSFCell cell = titleRow.createCell(i);
    cell.setCellValue(titles[i]);
    cell.setCellStyle(cellStyle);
}

5、合并单元格 

首先创建 CellRangeAddress对象,表示要合并的单元格范围,然后使用 addMergedRegion()方法合并单元格,以下这是CellRangeAddress的参数详解。

startRow开始行0,表示第1行
endRow结束行1,表示第2行
startColumn开始列2,表示第3列
endColumn结束列3,表示第4列

代码如下:

CellRangeAddress region = new CellRangeAddress(0, 0 , 0, titles.length-1);
sheet.addMergedRegion(region);

6、创建批注 

首先如果要在工作表上添加批注/图片/图形等元素,需要先调用createDrawingPatriarch()来获取工作表的绘制对象Drawing。

其次在工作表中创建单元格批注的对象,HSSFClientAnchor用于创建一个新的端锚,并设置锚的左下和右下坐标,用于图片插入,画线等操作。

HSSFClientAnchor的参数顺序如下:

左边距、上边距、右边距、下边距 、 开始列、开始行 、结束列、 结束行。

Drawing drawing = sheet.createDrawingPatriarch();
Comment comment = drawing.createCellComment(new HSSFClientAnchor(0, 0, 0, 0,
    (short) headerCell.getColumnIndex(),
    headerCell.getRowIndex(),
    (short) (headerCell.getColumnIndex() + 5),
    headerCell.getRowIndex() + 6));
    comment.setString(new HSSFRichTextString("这是标题信息哦!"));
headerCell.setCellComment(comment);

所以这段代码的意思是:在工作表上,创建了一个单元格批注comment,这个批注的锚点设置在从单元格headerCell开始,延伸5列6行。

7、遍历数据

最后我们通过循环来遍历我们集合当中的数据,上面已经讲过,这边不再多做讲解。

         for(int i = 0 ; i < students.size() ; i++ ){

            Student student = students.get(i);

            HSSFRow row = sheet.createRow(i+2);

            for (int j = 0; j < titles.length; j++) {
                HSSFCell cell = null;
                switch (j) {
                    case 0:
                        cell = row.createCell(j);
                        cell.setCellValue(i);
                        break;
                    case 1:
                        cell = row.createCell(j);
                        cell.setCellValue(student.getName());
                        break;
                    case 2:
                        cell = row.createCell(j);
                        cell.setCellValue(student.getSex());
                        break;
                    case 3:
                        cell = row.createCell(j);
                        cell.setCellValue(student.getAddress());
                        break;
                    case 4:
                        cell = row.createCell(j);
                        cell.setCellValue(student.getPhone());
                        break;
                }
            }
        }

8、设置响应下载

1、定义Excel文件名

2、把文件名编码为 ISO-8859-1格式,从而支持中文下载文件名

3、设置 Response为附件应答

4、设置附件名称为codeFileName,告诉浏览器这是一个附件应答

5、从workbook中获取输出流,写入内容到response输出流

6、关闭workbook,释放资源

String fileName = "学生表统计";
String codeFileName = new String((fileName + ".xls").getBytes("UTF-8"), "ISO-8859-1");
response.reset();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + codeFileName);
OutputStream out = response.getOutputStream();
workbook.write(response.getOutputStream());
out.flush();
out.close();
workbook.close();

9、运行截图

浏览器访问:http://localhost:8080/student/export

四、导入功能

1、获取单元格值方法

如果当前单元格的格式是时间格式,则需要特殊处理为时间格式,否则会报错。

String dataFormatString = cell.getCellStyle().getDataFormatString();
if(dataFormatString.equals("m/d/yy")){
    cellValue = new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
    return cellValue;
}

如果当前单元格是数字,比如1,那么读出来会默认是1.0,所以要把数字当成String来读。

if(cell.getCellType() == CellType.NUMERIC){
    cell.setCellType(CellType.STRING);
}

先判断读取的类型,来通过switch结构来获取单元格值。

//判断数据的类型
switch (cell.getCellType()){
    //数字
    case NUMERIC:
        cellValue = String.val
        break;
    //字符串
    case STRING:
        cellValue = String.val
        break;
    //Boolean
    case BOOLEAN:
        cellValue = String.val
        break;
    //公式
    case FORMULA:
        cellValue = String.val
        break;
    //空值
    case BLANK:
        cellValue = "";
        break;
    //故障
    case ERROR:
        cellValue = "非法字符";
        break;
    default:
        cellValue = "未知类型";
        break;
}

2、获取文件流

FileInputStream in = new FileInputStream("F:\\学生表统计.xls");

3、获取Excel文件对象

我这边我获取的是.xls后缀格式的文件

Workbook workbook = new HSSFWorkbook(in);

这个是获取.xlsx格式的对象 

Workbook workbook = new XSSFWorkbook(in);

4、获取工作簿

默认通过工作簿名称来获取工作簿对象

Sheet sheet = workbook.getSheet("学生表");

也可以通过下标来进行获取

Sheet sheet = workbook.getSheetAt(0);

5、获取首尾行下标

获取首行下标

int firstRowNum = sheet.getFirstRowNum();

获取尾行下标 

int lastRowNum = sheet.getLastRowNum();

6、读取数据 

使用for循环读取每行的第一列单元格的数据,获取数据的方法就是我上面封装好的方法。

for(int i = firstRowNum ; i <=lastRowNum ; i++){
    
    Row row = sheet.getRow(i);
    Cell cell = null;
    if(row != null){
        cell = row.getCell(0);
    }

    System.out.println(getCellValue(cell));

}

7、测试运行

我准备了7种不同类型的数据进行读取

单元测试结果如下,读取一切正常。 

五、完整代码

导入和导出的完整代码:

package com.example.excel.service;

import com.example.excel.domain.Student;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author HTT
 */
@Service
public class StudentService {

    public List<Student> initData(){
        List<Student> list = new ArrayList<>();
        Student student = new Student();
        student.setId(1);
        student.setName("张三");
        student.setSex("男");
        student.setAddress("江苏");
        student.setPhone("19991198111");
        list.add(student);
        student = new Student();
        student.setId(2);
        student.setName("李四");
        student.setSex("女");
        student.setAddress("南京");
        student.setPhone("1887119121");
        list.add(student);
        return list;
    }

    public void export(HttpServletResponse response) throws IOException {

        //获取学生数据
        List<Student> students = initData();
        //获取标题
        String[] titles = {"编号","姓名","性别","地址","电话"};
        //.xls格式
        HSSFWorkbook workbook = new HSSFWorkbook();

        //.xlsx格式
        //XSSFWorkbook workbook = new XSSFWorkbook();


        //新增工作表
        HSSFSheet sheet = workbook.createSheet("学生表");

        //单元格样式对象
        HSSFCellStyle cellStyle = this.getColumnStyle(workbook, true, true, HorizontalAlignment.CENTER,VerticalAlignment.CENTER);

        //创建第一行
        HSSFRow header = sheet.createRow(0);
        HSSFCell headerCell = header.createCell(0);
        headerCell.setCellValue("学生信息表");
        CellRangeAddress region = new CellRangeAddress(0, 0 , 0, titles.length-1);
        sheet.addMergedRegion(region);

        /**
         * - 左边距
         * - 上边距
         * - 右边距
         * - 下边距
         * - 开始列
         * - 开始行
         * - 结束列
         * - 结束行
         * 在工作表`drawing`上,
         * 创建了一个单元格批注 comment。
         * 这个批注的锚点设置在从单元格 headerCell 开始,延伸 5 列 6 行。
         */
        Drawing drawing = sheet.createDrawingPatriarch();
        Comment comment = drawing.createCellComment(new HSSFClientAnchor(0, 0, 0, 0,
                (short) headerCell.getColumnIndex(),
                headerCell.getRowIndex(),
                (short) (headerCell.getColumnIndex() + 5),
                headerCell.getRowIndex() + 6));
        comment.setString(new HSSFRichTextString("这是标题信息哦!"));

        headerCell.setCellComment(comment);

        //创建第一行
        HSSFRow titleRow = sheet.createRow(1);

        //写入标题
        for(int i = 0 ; i < titles.length ; i++ ){
            HSSFCell cell = titleRow.createCell(i);
            cell.setCellValue(titles[i]);
            cell.setCellStyle(cellStyle);
        }

        for(int i = 0 ; i < students.size() ; i++ ){

            Student student = students.get(i);

            HSSFRow row = sheet.createRow(i+2);

            for (int j = 0; j < titles.length; j++) {
                HSSFCell cell = null;
                switch (j) {
                    case 0:
                        cell = row.createCell(j);
                        cell.setCellValue(i);
                        break;
                    case 1:
                        cell = row.createCell(j);
                        cell.setCellValue(student.getName());
                        break;
                    case 2:
                        cell = row.createCell(j);
                        cell.setCellValue(student.getSex());
                        break;
                    case 3:
                        cell = row.createCell(j);
                        cell.setCellValue(student.getAddress());
                        break;
                    case 4:
                        cell = row.createCell(j);
                        cell.setCellValue(student.getPhone());
                        break;
                }
            }
        }


        String fileName = "学生表统计";
        String codeFileName = new String((fileName + ".xls").getBytes("UTF-8"), "ISO-8859-1");
        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + codeFileName);
        OutputStream out = response.getOutputStream();
        workbook.write(response.getOutputStream());
        out.flush();
        out.close();
        workbook.close();

    }

    /**
     * 单元格样式
     * @param workbook
     * @param fontBold 是否加粗
     * @param isBorder 是否带边框
     * @param horizontalAlignment 水平对齐格式
     * @param verticalAlignment 垂直对齐格式
     * @return
     */
    private HSSFCellStyle getColumnStyle(HSSFWorkbook workbook,
                                         boolean fontBold,
                                         boolean isBorder,
                                         HorizontalAlignment horizontalAlignment,
                                         VerticalAlignment verticalAlignment) {
        // 设置字体
        HSSFFont font = workbook.createFont();
        //设置字体大小
        font.setFontHeightInPoints((short) 12);
        //设置字体名字
        font.setFontName("宋体");
        font.setBold(fontBold);
        //设置样式;
        HSSFCellStyle style = workbook.createCellStyle();
        // 是设置前景色不是背景色
        style.setFillForegroundColor(IndexedColors.RED.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        if (isBorder) {
            //设置底边框;
            style.setBorderBottom(BorderStyle.THIN);
            //设置底边框颜色;
            style.setBottomBorderColor(IndexedColors.BLACK.index);
            //设置左边框;
            style.setBorderLeft(BorderStyle.THIN);
            //设置左边框颜色;
            style.setLeftBorderColor(IndexedColors.BLACK.index);
            //设置右边框;
            style.setBorderRight(BorderStyle.THIN);
            //设置右边框颜色;
            style.setRightBorderColor(IndexedColors.BLACK.index);
            //设置顶边框;
            style.setBorderTop(BorderStyle.THIN);
            //设置顶边框颜色;
            style.setTopBorderColor(IndexedColors.BLACK.index);
        }
        //在样式用应用设置的字体;
        style.setFont(font);
        //设置自动换行;
        style.setWrapText(false);
        //设置水平对齐的样式为居中对齐;
        style.setAlignment(horizontalAlignment);
        //设置垂直对齐的样式为居中对齐;
        style.setVerticalAlignment(verticalAlignment);
        return style;
    }

    /**
     * 获取单元格的值
     * @param cell
     * @return
     */
    public static String getCellValue(Cell cell){
        String cellValue = "";
        if(cell == null){
            return cellValue;
        }
        //如果当前单元格内容为日期类型,需要特殊处理
        String dataFormatString = cell.getCellStyle().getDataFormatString();
        if(dataFormatString.equals("m/d/yy")){
            cellValue = new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
            return cellValue;
        }
        //把数字当成String来读,避免出现1读成1.0的情况
        if(cell.getCellType() == CellType.NUMERIC){
            cell.setCellType(CellType.STRING);
        }
        //判断数据的类型
        switch (cell.getCellType()){
            //数字
            case NUMERIC:
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            //字符串
            case STRING:
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            //Boolean
            case BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            //公式
            case FORMULA:
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            //空值
            case BLANK:
                cellValue = "";
                break;
            //故障
            case ERROR:
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }


    public void analysis() throws IOException {
        // 通过输入流,读取excel文件
        FileInputStream in = new FileInputStream("F:\\学生表统计.xls");

        // excel文件对象
        Workbook workbook = new HSSFWorkbook(in);

        // 通过工作簿的名字获取工作簿
        Sheet sheet = workbook.getSheet("学生表");

        // 通过工作簿的下标获取工作簿
        //Sheet sheet = workbook.getSheetAt(0);

        // 获取首行下标
        int firstRowNum = sheet.getFirstRowNum();

        // 获取尾行下标
        int lastRowNum = sheet.getLastRowNum();

        for(int i = firstRowNum ; i <=lastRowNum ; i++){
            
            Row row = sheet.getRow(i);

            Cell cell = null;
            if(row != null){
                cell = row.getCell(0);
            }

            System.out.println(getCellValue(cell));

        }


    }
}

请求层

package com.example.excel.controller;

import com.example.excel.service.StudentService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
@RequestMapping("/student")
public class StudentController {

    @Resource
    private StudentService service;

    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {
        service.export(response);
    }
}

六、Gitee源码  

SpringBoot使用Apache操作Excel导入与导出: 主要汇总日常开发中常用的关于一些关于Excel导入导出功能详解。

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

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

相关文章

el-dialog 层级问题混乱

使用 element -UI 的弹窗时&#xff0c;一般来说弹窗的层级应该比较高&#xff0c;背景置灰。 下边这个弹窗是正常情况下的&#xff1a; 有时候出现这样的情况&#xff1a; 解决问题&#xff1a; 只需要 在标签里边添加 append-to-body 属性问题就解决了。

WPF TextBox 添加范围验证

WPF TextBox 添加范围验证 添加范围验证&#xff0c;若出现范围错误添加信息捕捉 使用到技术&#xff1a;使用ValidationRules实现范围验证&#xff0c;当范围出现错误时&#xff0c;可以通过触发器Validation.HasErrorTrue设置自定义错误样式。 使用Behavior技术捕捉所有验证…

1-Nginx介绍及安装(源码安装)

1.Nginx介绍 Nginx&#xff08;engine x&#xff09;是一个轻量级、高性能的HTTP和反向代理服务器&#xff0c;也是一个IMAP/POP3/SMTP服务器。 Nginx特点&#xff1a; ->占用内存少 ->并发能力强(3W/S) 2.Nginx安装 2.1.环境 [rootcentos79-3 ~]# cat /etc/redha…

未来网站开发必备:14个让你惊艳的JavaScript Web API!

微信搜索 【大迁世界】, 我会第一时间和你分享前端行业趋势&#xff0c;学习途径等等。 本文 GitHub https://github.com/qq449245884/xiaozhi 已收录&#xff0c;有一线大厂面试完整考点、资料以及我的系列文章。 快来免费体验ChatGpt plus版本的&#xff0c;我们出的钱 体验地…

进制(数制)及进制之间的转换汇总(超详细)

进制是一种表示数字的方法&#xff0c;它决定了数字在数值系统中的位置和权值。常见的进制包括十进制、二进制、八进制和十六进制。 1. 十进制&#xff08;decimal&#xff09;&#xff1a; 十进制是我们日常生活中最常用的进制&#xff0c;使用0-9这10个数字来表示。每一位的…

小研报 - 神奇的 SD 图(InsCode Stable Diffusion 美图活动一期)

一、 Stable Diffusion 模型 在线使用地址&#xff1a;https://inscode.csdn.net/inscode/Stable-Diffusion 二、模型版本及相关配置 Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 2391134711, Size: 512x512, Model hash: 74c61c3a52, Model: GuoFeng3, Version: v1.2…

【应用笔记】CW32 电容式触摸按键设计指南

前言 CW32 电容式触摸按键设计指南向客户提供一种利用 CW32 内部资源结合软件编程实现电容式触摸按键有效 触摸检测的方法。本指南的内容重点在于工作原理、软件检测过程以及调试指引。 利用芯源半导体的 CW32 系列小规模 MCU 的 IO、比较器、定时器、高速高精度内置 RC 时钟…

C++ 实现跳表

目录 1.什么是跳表-skiplist 2.skiplist的效率如何保证&#xff1f; 3.skiplist的实现 4.skiplist跟平衡搜索树和哈希表的对比 1.什么是跳表-skiplist skiplist 本质上也是一种查找结构&#xff0c;用于解决算法中的查找问题&#xff0c;跟平衡搜索树和哈希表的价值是一样…

计算机毕业论文内容参考|基于C的空中战机游戏设计与实现

文章目录 导文文章重点摘要前言绪论1课题背景2国内外现状与趋势3课题内容相关技术与方法介绍系统分析系统设计系统实现系统测试总结与展望1本文总结2后续工作展望导文 计算机毕业论文内容参考|基于C的空中战机游戏设计与实现 文章重点 摘要 本文将介绍基于C编程语言的空中战机…

【电影推荐系统】数据加载

目录 数据集 解释 movie.csv ratings.csv tag.csv 数据预处理 mongodb 将数据按照csv文件里的分割符进行分割&#xff0c;转换为DF Moive Rating Tag es 将mongo集合tag 根据mid tag > mid tags(tag1|tag2|tag3...) moive 添加一列 tags 导入后数据库信息 mong…

python爬虫_正则表达式获取天气预报并用echarts折线图显示

文章目录 ⭐前言⭐python re库&#x1f496; re.match函数&#x1f496; re.search函数&#x1f496; re.compile 函数 ⭐正则获取天气预报&#x1f496; 正则实现页面内容提取&#x1f496; echarts的天气折现图 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分…

SpringBoot使用EasyExcel批量导出500万数据

SpringBoot使用EasyExcel批量导出500万数据 说明excel版本比较EasyExcel介绍项目目录mysql对应表建表语句pom.xmlapplication.yml配置类启动类代码OrderInfo 实体类OrderInfoExcel excel模版标题类(EasyExcel需要使用这个)TestController控制层接口层TestServiceTestServiceImp…

L298N模块驱动2项4线步进电机的多种方法及其优缺点

摘要&#xff1a;本文将详细介绍L298N模块驱动2项4线步进电机的多种方法&#xff0c;并分析各种方法的优缺点。在实例程序中&#xff0c;将展示不同方法的代码示例&#xff0c;帮助读者理解并实际应用。 引言&#xff1a; 步进电机作为一种常用的电机类型&#xff0c;在许多嵌入…

估值 2 个月从 11 亿美元降到 3 亿美元,投资人清仓跑路,国产大模型创业遇冷...

图片来源&#xff1a;由无界 AI生成 创业未半&#xff0c;而中道崩殂。 6 月 29 日&#xff0c;美团发布公告以 20.65 亿元全资收购光年之外全部权益&#xff0c;距离光年之外正式营业刚过去 84 天。 这是目前中国大模型创业领域最大的收购案&#xff0c;光年之外也在 4 个月时…

HTML5 游戏开发实战 | 黑白棋

黑白棋&#xff0c;又叫反棋(Reversi)、奥赛罗棋(Othello)、苹果棋、翻转棋。黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子&#xff0c;最后以棋盘上谁的棋子多来判断胜负。黑白棋的棋盘是一个有88方格的棋盘。开始时在棋盘正中有两白两黑四个棋子交叉放置&#xff0…

观察级水下机器人第一次使用总结2023年6月

最近有个科研项目需要用到ROV&#xff0c;其合同三年之前就签订了&#xff0c;由于疫情的影响&#xff0c;一直没有执行。刚好我们的ROV也验收了&#xff0c;正好派上用场。因为属于ROV使用的菜鸟级&#xff0c;我们邀请厂家无锡智海张工和陈工&#xff0c;中海辉固ROV操作经验…

纵向越权-业务安全测试实操(32)

纵向越权 某办公系统普通用户权限越权提升为系统权限 服务器为鉴别客户端浏览器会话及身份信息,会将用户身份信息存储在 Cookie中, 并发送至客户端存储。攻击者通过尝试修改Cookie中的身份标识为管理员,欺骗服务器分 配管理员权限,达到垂直越权的目的,如图所示。 某办公系…

「原汤话原食」更名「记者下班」,一切才刚刚开始

大家好&#xff0c;我是《原汤话原食》的小黑。这可能是我最后一次这样介绍自己。 毕竟&#xff0c;以后&#xff0c;我就得说&#xff0c;我是《记者下班》的小黑了。 事情是这样的&#xff1a; 2023年7月5日&#xff0c;津津乐道播客网络旗下《原汤话原食》节目正式更名为《记…

Claude使用教程,解决Claude不能回复

Claude是ChatGPT最为有⼒的竞争对⼿之⼀&#xff0c;Claude 的研发公司是专注人工智能安全和研究的初创公司 Anthropic&#xff0c;由前 OpenAI 员工共同创立的。今年 3 月份 Anthropic 获得了谷歌 3 亿美元的投资&#xff0c;谷歌也因此获得其 10% 股份。 ⽬前可以通过官⽹加…

day29-Oracle

0目录 第一章 Oracle 1.1 Oracle表空间-创建&#xff1a; 1.2 Oracle表空间-删除&#xff1a; 1.3 Oracle常用用户&#xff08;内置&#xff09;&#xff1a;&#xff08;1&#xff09;sys 超级用户&#xff1a; 定义&#xff1a;它是Oracle中的超级账户&#xff0…