EasyExcel导入导出

news2024/9/25 1:14:37

在项目开发中往往需要使用到数据的导入和导出,导入就是从Excel中导入到DB中,而导出就是从DB中查询数据然后使用POI写到Excel上。所以今天就为大家带来一款基于阿里EasyExcel的导入导出功能,开放了一个demo,以下是gitee地址,有兴趣的可以去看看:EasyExcelDemo:基于EasyExcel实现导入导出的简易demo

该demo以及我下面所要分享的都是使用的mongodb来做的,使用mysql的小伙伴大同小异,自己改造一下,后续如果有时间的话我会在gitee以及这里更新mysql的方式

1.引入依赖

<!--easyexcel-->
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>easyexcel</artifactId>
   <version>3.0.5</version>
</dependency>
<!-- 随机数据生成 -->
<dependency>
   <groupId>com.apifan.common</groupId>
   <artifactId>common-random</artifactId>
   <version>1.0.16</version>
</dependency>

2.测试数据制造

可以看到,在上面的maven中,我提到了一个随机数据生成的依赖,这个依赖是我在网上找到的,简直就是解放了我们的双手(当时我是打算通过手敲方法,调用方法来生成的,下载了demo的可以在工具类中看到,我已经写了不少了手动封装数据的方法);详细的使用方式步骤,更多的数据生成方式可以参考这篇博客:Java-随机数据生成器

调用数据生成方法:

/**
     * 随机生成一条用户数据
     *
     * @return
     */
    public static Map createUserdata() {
        //生成1个随机中文人名(性别随机)
        String userName = PersonInfoSource.getInstance().randomChineseName();
        //生成1个随机中国大陆手机号
        String phone = PersonInfoSource.getInstance().randomChineseMobile();
        //生成1个随机QQ号
        String qqNumber = PersonInfoSource.getInstance().randomQQAccount();
        //生成1个随机邮箱地址,后缀为163.com,邮箱用户名最大长度为10
        String email = InternetSource.getInstance().randomEmail(10, "163.com");
        //生成1个2000年的随机日期,日期格式为yyyy-MM-dd
        String borthday = DateTimeSource.getInstance().randomDate(2000, "yyyy-MM-dd");
        //生成过去36000秒范围内的随机时间
        LocalDateTime lastLogintime = DateTimeSource.getInstance().randomPastTime(LocalDateTime.now(), 36000);
        //生成1个随机强密码,长度为16,无特殊字符
        String pwd = PersonInfoSource.getInstance().randomStrongPassword(16, false);
        //生成1个随机中国大陆详细地址
        String addr = AreaSource.getInstance().randomAddress();
        //生成1个随机英文人名
        String nikName = PersonInfoSource.getInstance().randomEnglishName();
        //生成1个随机虚拟银联信用卡号码
        String bankCard = PersonInfoSource.getInstance().randomCreditCardNo(CreditCardType.UnionPay);

        Map data = new HashMap();
        data.put("userName", userName);
        data.put("phone", phone);
        data.put("qqNumber", qqNumber);
        data.put("email", email);
        data.put("borthday", borthday);
        data.put("pwd", pwd);
        data.put("lastLogintime", lastLogintime);
        data.put("addr", addr);
        data.put("nikName", nikName);
        data.put("bankCard", bankCard);

        return data;
    }

swagger接口调用生成100w条数据:

 生成结果:

 3.创建实体类

@NoArgsConstructor
@AllArgsConstructor
@Data
public class UserData {
    @ExcelProperty(value = "姓名") // 导出后的表头名称
    private String userName;
    @ExcelProperty(value = "银行卡号")
    private String bankCard;
    @ExcelProperty(value = "电话号码")
    private String phone;
    @ExcelProperty(value = "家庭住址")
    private String addr;
    @ExcelProperty(value = "别名")
    private String nikName;
    @ExcelProperty(value = "QQ号")
    private String qqNumber;
    @ExcelProperty(value = "邮箱")
    private String email;
    @ExcelProperty(value = "生日")
    private String borthday;
    @ExcelProperty(value = "密码")
    private String pwd;
    @ExcelProperty(value = "最后登录时间")
    private String lastLogintime;
    @ExcelProperty(value = "创建人")
    private String creatUser;
    @ExcelProperty(value = "更新者")
    private String updateUser;
}

注意:我这里创建的实体类是与我生成数据的字段所对应的,需求不同请酌情修改

4.导出

接口:

@PostMapping("/exportExcel")
    @ApiOperation(value = "导出用户数据", notes = "导出用户数据详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "num", value = "文件导出页数", required = true, dataType = "Long", defaultValue ="2"),
            @ApiImplicitParam(name = "enable", value = "是否开启分页", required = true, dataType = "Boolean", defaultValue ="false")
    })
    public ResponseEntity exportExcel(@RequestParam(defaultValue = "2") Long num,@RequestParam(defaultValue = "false") Boolean enable) {
        excelService.exportExcel(num, enable);
        ResponseEntity<String> entity = new ResponseEntity<>("OK", HttpStatus.OK);
        return entity;
    }

核心代码:

/**
     * 导出表格
     *
     * @param num    导出页数;若开启分页参数为false则此参数无效
     * @param enable 是否开启分页
     */
    @Override
    public void exportExcel(Long num, Boolean enable) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        export(num, enable);
        stopWatch.stop();
        logger.info("共计耗时: " + stopWatch.getTotalTimeSeconds() + "S");
    }
/**
     * 导出所有用户数据
     *
     * @param num
     * @param enable
     */
    public void export(Long num, Boolean enable) {
        String collectionName = "test.user.manyData";
        OutputStream outputStream = null;
        try {
            // 获取当前线程的请求属性
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletResponse response = requestAttributes.getResponse();
            outputStream = response.getOutputStream();
            // 创建文件导出流
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            // 是否开启分页
            if (enable) {
                // 统计数据库中的数据总数
                Integer totalCount = Math.toIntExact(mongoTemplate.count(new Query(), collectionName));
                // 根据总数,计算每页需要多少条数据
                Integer floor = (int) Math.floor(totalCount / num.intValue());
                // 每一个Sheet页需要存放的数据条数
                Integer sheetDataRows = floor;
                // 每次写入的数据量
                Integer writeDataRows = floor;
                // 计算需要的Sheet数量
                Integer sheetNum = num.intValue();
                // 计算一般情况下每一个Sheet需要写入的次数(一般情况不包含最后一个sheet,因为最后一个sheet不确定会写入多少条数据)
                Integer oneSheetWriteCount = sheetDataRows / writeDataRows;
                // 计算最后一个sheet需要写入的次数
                Integer lastSheetWriteCount = totalCount % sheetDataRows == 0 ? oneSheetWriteCount : (totalCount % sheetDataRows % writeDataRows == 0 ? (totalCount / sheetDataRows / writeDataRows) : (totalCount / sheetDataRows / writeDataRows + 1));
                // 开始分批查询分次写入
                for (int i = 0; i < sheetNum; i++) {
                    // 创建Sheet
                    WriteSheet sheet = new WriteSheet();
                    sheet.setSheetName("人员页数" + i);
                    sheet.setSheetNo(i);
                    // 循环写入次数: j是当目前不是最后一个Sheet的时候写入次数为正常的每个Sheet写入的次数,如果是最后一个就需要使用计算的次数lastSheetWriteCount
                    for (int j = 0; j < (i != sheetNum - 1 ? oneSheetWriteCount : lastSheetWriteCount); j++) {
                        Query query = new Query();
                        query.skip(i * floor); // 跳过前面的 pageNo-1 页(已查询的记录数)
                        query.limit(floor); // 返回 pageSize 条记录(每页显示的记录数)
                        List<UserData> userDataList = mongoTemplate.find(query, UserData.class, collectionName);
                        WriteSheet writeSheet = EasyExcel.writerSheet(i, "用户信息" + (i + 1)).head(UserData.class)
                                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
                        // 写数据
                        excelWriter.write(userDataList, writeSheet);
                    }
                }
            } else {
                Query query = new Query();
                // 全量查询所有数据
                List<UserData> userDataList = mongoTemplate.find(query, UserData.class, collectionName);
                WriteSheet writerSheet = EasyExcel.writerSheet(0, "用户信息").head(UserData.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
                excelWriter.write(userDataList, writerSheet);
            }
            // 下载EXCEL
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止浏览器端导出excel文件名中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("用户详细信息表格", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            // 关流
            excelWriter.finish();
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (BeansException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

导出测试:

100W数据导出耗时:

文件大小:

swagger填写参数(分10页):

 结果查看:

 可以看到,1分钟完成了百万级的数据导出,性能就不用多说了吧

5.导入

这里导入功能,我做了俩个接口,一个是获取导入的excel模板的接口,另一个则是导入excel到数据库的接口

接口:

@GetMapping("/exportTemplateExcel")
    @ApiOperation(value = "导出用户数据模板", notes = "导出用户数据模板")
    public ResponseEntity exportTemplateExcel() {
        excelService.exportTemplateExcel();
        ResponseEntity<String> entity = new ResponseEntity<>("OK", HttpStatus.OK);
        return entity;
    }

    @PostMapping("/importExcel")
    @ApiOperation(value = "导入用户数据", notes = "导入用户数据详细信息")
    public ResponseEntity importExcel(@RequestParam("file") MultipartFile multipartFile) {
        String importExcelPath = excelService.importExcel(multipartFile);
        long startReadTime = System.currentTimeMillis();
        System.out.println("------开始读取Excel的Sheet时间(包括导入数据过程):" + startReadTime + "ms------");
        // 读取所有Sheet的数据.每次读完一个Sheet就会调用这个方法
        EasyExcel.read(importExcelPath, new EasyExceGeneralDatalListener(excelService)).doReadAll();
        long endReadTime = System.currentTimeMillis();
        System.out.println("------读取Excel的Sheet时间(包括导入数据)共计耗时:" + (endReadTime-startReadTime) + "ms------");

        ResponseEntity<String> entity = new ResponseEntity<>("OK", HttpStatus.OK);
        return entity;
    }

 核心代码部分:

导出模板代码:

/**
     * 导出表格模板文件
     */
    @Override
    public void exportTemplateExcel() {
        OutputStream outputStream = null;
        try {
            // 获取当前线程的请求属性
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletResponse response = requestAttributes.getResponse();
            // 创建一个输出流
            outputStream = response.getOutputStream();
            // build输出
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            // 填写sheet页
            WriteSheet writerSheet = EasyExcel.writerSheet(0, "用户信息模板").head(UserData.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
            // 写出模板文件
            excelWriter.write(new ArrayList<>(), writerSheet);

            // 下载EXCEL,设置响应参数
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 设置响应参数,这里URLEncoder.encode可以防止浏览器端导出excel文件名中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("用户详细信息表格", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            // 关流
            excelWriter.finish();
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (BeansException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

 导入数据代码:

/**
     * 导入表格,保存到本地
     *
     * @param multipartFile  表格参数原件
     * @return
     */
    @Override
    public String importExcel(MultipartFile multipartFile) {
        try {
            // 获取上传的文件信息
            String fileName = multipartFile.getOriginalFilename();
            // 保存上传的文件到本地磁盘
            Path dest = Paths.get("C:\\Users\\IDLINK\\Desktop\\文档说明\\", fileName);
            Files.copy(multipartFile.getInputStream(), dest);
            return dest.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
/**
     * 保存数据到mongo
     *
     * @param dataList
     */
    @Override
    public void importData(List<Map<Integer, String>> dataList) {
        String collectionName = "test.user.manyData";
        //结果集中数据为0时,结束方法.进行下一次调用
        if (dataList.size() == 0) {
            return;
        }
        try {
            long startTime = System.currentTimeMillis();
            logger.info(dataList.size() + "条,开始导入到数据库时间:" + startTime + "ms");
            List list = new ArrayList();
            for (int i = 1; i < dataList.size(); i++) {
                Map<Integer, String> item = dataList.get(i);
                if (StringUtils.isBlank(item.get(0))||StringUtils.isBlank(item.get(1))||StringUtils.isBlank(item.get(2))
                        ||StringUtils.isBlank(item.get(3))||StringUtils.isBlank(item.get(7))||StringUtils.isBlank(item.get(8))){
                    throw new RuntimeException(String.format("必填字段不能为空!"));
                }
                UserData userData = new UserData();
                userData.setUserName(item.get(0));
                userData.setBankCard(item.get(1));
                userData.setPhone(item.get(2));
                userData.setAddr(item.get(3));
                userData.setNikName(item.get(4));
                userData.setQqNumber(item.get(5));
                userData.setEmail(item.get(6));
                userData.setBorthday(item.get(7));
                userData.setPwd(item.get(8));
                userData.setLastLogintime(item.get(9));
                userData.setCreatUser(item.get(10));
                userData.setUpdateUser(item.get(11));
                list.add(userData);
            }
            mongoTemplate.insert(list, collectionName);
            long endTime = System.currentTimeMillis();
            logger.info(dataList.size() + "条,结束导入到数据库时间:" + endTime + "ms");
            logger.info(dataList.size() + "条,导入用时:" + (endTime - startTime) + "ms");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

注意:该easyexcel导入需要配合导入监听类AnalysisEventListener来实现,以下就不过多介绍,我直接把监听类代码贴在下面,可以直接使用,如果不清楚的还是建议去我提供的gitee看看

/**
 * 导入事件监听类,只要有文件传入就会调用read方法,就会触发该监听器
 */
public class EasyExceGeneralDatalListener extends AnalysisEventListener<Map<Integer, String>> {
    /**
     * 处理业务逻辑的Service,也可以是Mapper
     */
    @Autowired
    private ExcelService empService;

    /**
     * 用于存储读取的数据
     */
    private List<Map<Integer, String>> dataList = new ArrayList<Map<Integer, String>>();

    public EasyExceGeneralDatalListener() {
    }

    public EasyExceGeneralDatalListener(ExcelService empService) {
        this.empService = empService;
    }

    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        //数据add进入集合
        dataList.add(data);
        //size是否为10000条:这里其实就是分批.当数据等于1w的时候执行一次插入
        if (dataList.size() >= 10000) {
            //存入数据库:数据小于1w条使用Mybatis的批量插入即可;
            saveData();
            //清理集合便于GC回收
            dataList.clear();
        }
    }

    /**
     * 保存数据到DB
     *
     * @param
     * @MethodName: saveData
     * @return: void
     */
    private void saveData() {
        empService.importData(dataList);
        dataList.clear();
    }

    /**
     * Excel中所有数据解析完毕会调用此方法
     *
     * @param: context
     * @MethodName: doAfterAllAnalysed
     * @return: void
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        dataList.clear();
    }
}

导入测试:

首先删除集合

在swagger中上传文件:

 

注意:需要在yml中配置文件上传大小,否则可能会报错(大小超过限制) ,详细配置信息如下:

spring:
  servlet:
    multipart:
      enabled: true
      file-size-threshold: 2KB
      max-file-size: 200MB
      max-request-size: 200MB

导入耗时1分钟:

 刷新mongo集合,查看数据量是否正确

 

百万条数据完美导入;耗时一分钟 

6.更多使用方式可以查看官方文档:

官方文档网址:EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel

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

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

相关文章

2.4 逻辑代数的基本定理

学习目标&#xff1a; 如果我要学习逻辑代数的基本定理&#xff0c;我会采取以下步骤&#xff1a; 1. 学习基本概念&#xff1a;首先&#xff0c;我会花时间了解逻辑代数的基本概念&#xff0c;如逻辑运算符&#xff08;合取、析取、否定等&#xff09;、真值表、逻辑等价性等…

Splashtop 与 Pax8 合作为 MSP 提供简化的远程支持解决方案

2023年4月27日 科罗拉多州丹佛 Pax8 是一个行业领先的云商务市场&#xff0c;该公司今天宣布将通过 Pax8 市场在全球推出其全新运营供应商 Splashtop。Splashtop 的远程访问、支持以及端点监控和管理解决方案极具成本效益&#xff0c;而且功能强大&#xff0c;可以助力托管服务…

Java使用JDBC连接PostgreSQL——使用maven,简单配置

目录 前置准备代码 前置准备 因为连接PostgreSQL需要先安装PG&#xff0c;所以以下给出PG的简单安装教程&#xff1a; window安装PostgreSQL 对应的建表语句&#xff1a; DROP TABLE IF EXISTS student; CREATE TABLE student (id serial NOT NULL,name varchar(100) NOT NU…

2023「光亚展」观察:规模空前,智能化趋势已势不可挡

6月12日&#xff0c;第二十八届广州国际照明展览会&#xff08;GILE&#xff09;及第二十届广州国际建筑电气技术展览会&#xff08;GEBT&#xff09;落下帷幕&#xff0c;共计汇聚了来自18个国家及地区的3,318家参展商&#xff0c;总展览面积达到了220,000平方米。 「智哪儿」…

ROS学习中遇到的问题以及解决方案

目录 问题1. 在使用xarco建立urdf时&#xff0c;运行joint_state_publisher/joint_state_publisher_gui报错问题2. 使用amcl定位时报No laser scan received警告&#xff0c; /scan 话题有数据&#xff0c;amcl也订阅了该话题。问题3. 运行.py文件报错问题4. 在roalaunch一个la…

Springboot整合Elasticsearch(一):Linux下安装 Elasticsearch 8.x

1、下载安装包&#xff0c;官方下载地址&#xff1a; Past Releases of Elastic Stack Software | Elastic elasticsearch-8.8.1-linux-x86_64.tar.gz 2、拷贝到 Linux 服务器上&#xff0c; 执行解压缩命令 安装包路径&#xff1a;/home/ELK_8.8.1 [rootlocalhost ELK_8.8.1]…

使用VNISEdit为PyQGIS程序制作一个安装包

引言 通常一个需要发布的程序都需要使用安装包进行安装&#xff0c;不可能给客户发送一套程序和依赖性文件&#xff0c;这样如果需要桌面添加软件的快捷方式&#xff0c;就得让客户自己添加&#xff08;因为每台电脑、每个用户的桌面路径是不一样的&#xff09;&#xff0c;非常…

改善客户体验是客户管理系统的重要价值

在如今竞争激烈的商业环境中&#xff0c;企业需要更好地了解客户需求、偏好和行为&#xff0c;以便提供更好的服务并保持客户忠诚度。这就是为什么越来越多的企业开始使用客户管理系统&#xff08;CMS&#xff09;来改善客户体验。 客户管理系统是一种专门设计用于帮助企业跟踪…

Day05 03-MySQL主从-主主原理与搭建详解

文章目录 第十六章 MySQL的系统架构&#xff08;主从架构&#xff09;16.1 MySQL集群架构的介绍16.1.1 主从架构介绍16.1.2 主从复制的原理 16.2 MySQL主从复制的实现16.2.1 环境说明16.2.2 主库配置16.2.3 从库配置16.2.4 主从复制测试 16.3 MySQL主主复制的实现16.3.1 主主复…

移植好U8g2图形库的STM32F407标准库工程模板,0.96寸OLED驱动程序

移植好U8g2图形库的STM32F407标准库工程模板&#xff0c;用的0.96寸OLED屏&#xff08;SSD1306&#xff09;&#xff0c;用硬件IIC驱动。 花了一晚上时间去移植。开发板主控MCU用的是STM32F407VET6&#xff0c;I2C接口用I2C1&#xff0c;SCL接PB6&#xff0c;SDA接PB7。 嵌入…

从分布式到微服务解密“架构”原理与实战笔记

分布式架构与微服务平台是当今IT界的关键技术&#xff0c;也是资深软件工程师和系统架构师必须掌握的核心技术。 微服务、云原生、Kubernetes、Service Mesh是分布式领域的热点技术&#xff0c;它们并不是凭空出现的&#xff0c;一定继承了某些“前辈”的优点。我们不仅要了解…

网络安全零基础之从原理看懂的XSS

01、XSS 的原理和分类 跨站脚本攻击 XSS(Cross Site Scripting)&#xff0c;为了不和层叠样式表(Cascading Style Sheets&#xff0c;CSS)的缩写混淆 故将跨站脚本攻击缩写为 XSS&#xff0c;恶意攻击者往 Web 页面里插入恶意 Script 代码&#xff0c;当用户浏览该页面时&…

软件测试将会赢来陌路?

最近参加了某大厂总监做的一场测试培训&#xff0c;感触颇深&#xff0c;一句话萦绕在耳畔“测试乃至测开&#xff0c;大厂为了降本增效这些都要被优化掉”。去年由他操刀优化了一大批优秀的测试员&#xff01; 实际小酋这几年已经有切身体会&#xff0c;测试野蛮增长的阶段已经…

cv学习--图像分类完结

深度学习面试题05&#xff1a;激活函数sigmod、tanh、ReLU、LeakyRelu、Relu6 - 黎明程序员 - 博客园 (cnblogs.com)

解惑:测试圈网红工具 Jmeter 到底难在哪里

同样的起点&#xff0c;同样的工作时间&#xff0c;为什么别人接那么多项目&#xff0c;你还是在点点点&#xff1b;为什么别人升职了&#xff0c;而你还在原地踏步&#xff1f; 同样的工作内容&#xff0c;为什么别人下班了&#xff0c;你还在加班&#xff1f; 在现在竞争激烈…

Unity入门4——重要组件与API

一、GameObject &#xff08;一&#xff09;成员变量 // 名字 print(this.gameObject.name); this.gameObject.name "Lesson4唐老狮改名"; print(this.gameOb…

手机号码应该如何选择呢?一文解决你的选择困难症!

哈喽大家好&#xff0c;我是搜卡之家葫芦弟。最近有一些小伙伴们私信葫芦弟&#xff0c;想办一个本地的手机号&#xff0c;想着长久一直使用的。既然是长久使用&#xff0c;那就想选一个不错的号码&#xff0c;手机靓号的话&#xff0c;好一点的号码价格又太贵。这不是要在平凡…

参与PK赢大奖!阿里云机器学习平台PAI助力开发者激发AIGC潜能

近年来&#xff0c;随着海量多模态数据在互联网的爆炸性增长和训练深度学习大模型的算力大幅提升&#xff0c;AI生成内容&#xff08;AI Generated Content&#xff0c;AIGC&#xff09;的应用呈现出爆发性增长趋势。为助力开发者能够一站式快速搭建文生图、对话等热门场景应用…

GPT问题摘录go中接口实现和继承

go如何实现接口 package mainimport "fmt"type Shape interface {Area() float64 }type Circle struct {Radius float64 }func (c Circle) Area() float64 {return 3.14 * c.Radius * c.Radius }func main() {c : Circle{Radius: 6.2}fmt.Println(c.Area()) } 首先我…

在线合并Excel文档的HTML网页工具

构建一个在线合并Excel文档的HTML网页工具 导语&#xff1a; 在本篇技术分享文章中&#xff0c;我将向您展示如何使用HTML、CSS和JavaScript构建一个功能强大的在线合并Excel文档的网页工具。这个工具可以帮助用户将多个Excel文件合并成一个文件&#xff0c;提高工作效率和方便…