Springboot3+EasyExcel由浅入深

环境介绍

技术栈

springboot3+easyexcel

软件

版本

IDEA

IntelliJ IDEA 2022.2.1

JDK

17

Spring Boot

3

EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。

他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。

官网https://easyexcel.opensource.alibaba.com/

Sheet工作簿

Row,行,索引从0开始

Column,列,索引从0开始

Cell,单元格

目录

Read

Read1

Read2

异常处理

读sheet

自定义格式转换 日期,数字-Read

自定义转换器-Read

读指定行

Write

Write1

Write2

写入指定列

多级列名

自定义格式转换 日期,数字-Write

自定义转换器-Write

指定列宽行高

批量写入excel方法

自定义模板写入excel

自定义监听器

Web上传下载


Read

Read1

List<Corrdinate> newlist =new ArrayList<>();String fileName="C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx";EasyExcel.read(fileName, Corrdinate.class, new ReadListener<Corrdinate>() {@Overridepublic void invoke(Corrdinate corrdinate, AnalysisContext analysisContext) {try {if (11<=Double.parseDouble(corrdinate.getX()) && Double.parseDouble(corrdinate.getX())<120&& 2<=Double.parseDouble(corrdinate.getY()) && Double.parseDouble(corrdinate.getY())<244 ){corrdinate.setZ(true);}else {corrdinate.setZ(false);}newlist.add(corrdinate);}catch (Exception e){System.out.println(e);corrdinate.setDesc("类型转换失败");newlist.add(corrdinate);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {System.out.println("读取完成");}}).sheet().doRead();

Read2

String fileName="C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx";EasyExcel.read(fileName, Corrdinate.class,new PageReadListener<Corrdinate>(corrdinates -> {for (Corrdinate corrdinate : corrdinates) {try {if (1<=Double.parseDouble(corrdinate.getX()) && Double.parseDouble(corrdinate.getX())<110&& 2<=Double.parseDouble(corrdinate.getY()) && Double.parseDouble(corrdinate.getY())<240 ){corrdinate.setZ(true);}else {corrdinate.setZ(false);}newlist.add(corrdinate);}catch (Exception e){System.out.println(e);corrdinate.setDesc("类型转换失败");newlist.add(corrdinate);}}})).sheet().doRead();

异常处理

重写onException方法

@Test
void readException() {List<Corrdinate> oldlist =new ArrayList<>();List<Corrdinate> newlist =new ArrayList<>();String fileName="C:\\Users\\Administrator\\Desktop\\坐标测试.xlsx";EasyExcel.read(fileName, Corrdinate.class, new ReadListener<Corrdinate>() {@Overridepublic void invoke(Corrdinate corrdinate, AnalysisContext analysisContext) {if (1<=Double.parseDouble(corrdinate.getX()) && Double.parseDouble(corrdinate.getX())<110&& 2<=Double.parseDouble(corrdinate.getY()) && Double.parseDouble(corrdinate.getY())<240 ){corrdinate.setZ(true);}else {corrdinate.setZ(false);}newlist.add(corrdinate);}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {System.out.println("读取完成");}@Overridepublic void onException(Exception exception, AnalysisContext context) throws Exception {System.out.println(exception);}}).sheet().doRead();for (Corrdinate corrdinate : newlist) {System.out.println(corrdinate.toString());}
}

try- catch

@Test
void read1() {List<Corrdinate> oldlist =new ArrayList<>();List<Corrdinate> newlist =new ArrayList<>();String fileName="C:\\Users\\Administrator\\Desktop\\测试.xlsx";EasyExcel.read(fileName, Corrdinate.class, new ReadListener<Corrdinate>() {@Overridepublic void invoke(Corrdinate corrdinate, AnalysisContext analysisContext) {try {if (1<=Double.parseDouble(corrdinate.getX()) && Double.parseDouble(corrdinate.getX())<200&& 20<=Double.parseDouble(corrdinate.getY()) && Double.parseDouble(corrdinate.getY())<300 ){corrdinate.setZ(true);}else {corrdinate.setZ(false);}newlist.add(corrdinate);}catch (Exception e){System.out.println(e);corrdinate.setDesc("类型转换失败");newlist.add(corrdinate);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {System.out.println("读取完成");}}).sheet().doRead();for (Corrdinate corrdinate : newlist) {System.out.println(corrdinate.toString());}
}

读sheet

读所有工作簿

@Test
void readManyShoot() {String fileName="C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx";EasyExcel.read(fileName, Corrdinate.class,new PageReadListener<>(corrdinates -> {corrdinates.forEach(System.out::println);})).doReadAll();
}

读任意工作簿

@Test
void readAppointSheet() {try (ExcelReader excelReader = EasyExcel.read("C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx").build();){//创建工作簿对象sheet1ReadSheet sheet1 = EasyExcel.readSheet(0).head(Corrdinate.class).registerReadListener(new PageReadListener<>(corrdinates -> {corrdinates.forEach(System.out::println);})).build();//创建工作簿对象sheet2ReadSheet sheet2 = EasyExcel.readSheet("Sheet2").head(Corrdinate.class).registerReadListener(new PageReadListener<>(corrdinates -> {corrdinates.forEach(System.out::println);})).build();excelReader.read(sheet1,sheet2);}
}

自定义格式转换 日期,数字-Read

@Data
public class man {
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("日期")
    @DateTimeFormat("yyyy年mm月dd日")
    private Date date;
    @ExcelProperty("成功率")
    private BigDecimal successrate;
}

自定义转换器-Read

public class StringConverterString implements Converter<String> {//支持java类型@Overridepublic Class<?> supportJavaTypeKey() {return String.class;}//支持Excel单元格类型@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}//读的数据符合类型@Overridepublic String convertToJavaData(ReadConverterContext<?> context) throws Exception {//转换return "姓名:"+context.getReadCellData().getStringValue();}//写的数据符合类型@Overridepublic WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) throws Exception {return new WriteCellData<>(context.getValue());}
}@Data
public class man {@ExcelProperty(converter = StringConverterString.class)private String name;@ExcelProperty("日期")@DateTimeFormat("yyyy年mm月dd日")private Date date;@ExcelProperty("成功率")private BigDecimal successrate;
}

读指定行

EasyExcel默认从第一行开始读取,第0行默认为列头

@Test
void selectRead(){String fileName="C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx";EasyExcel.read(fileName, man.class,new PageReadListener<>(mans -> {mans.forEach(System.out::println);})).sheet("Sheet3").headRowNumber(2)//第几行,0-n.doRead();
}

Write

实体类

@Datapublic class Corrdinate {private long id;@ExcelProperty("x")private String x;private String y;@ExcelProperty("是否匹配")private boolean z;@ExcelProperty("描述")private String desc;@ExcelIgnore//忽略字段private String de;}

Write1

//生成数据方法private List<Corrdinate> getData(int count) {List<Corrdinate> list = ListUtils.newArrayList();for (int i = 0; i < count; i++) {Corrdinate corrdinate = new Corrdinate();//生成10-100随机数corrdinate.setId(RandomUtil.randomInt(10, 100));corrdinate.setX(String.valueOf(RandomUtil.randomInt(10, 100)));corrdinate.setY(String.valueOf(RandomUtil.randomInt(10, 100)));list.add(corrdinate);}return list;}@Testvoid write1(){EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Corrdinate.class).sheet()//指定工作簿

Write2

//生成数据方法private List<Corrdinate> getData(int count) {List<Corrdinate> list = ListUtils.newArrayList();for (int i = 0; i < count; i++) {Corrdinate corrdinate = new Corrdinate();corrdinate.setId(Long.parseLong(String.valueOf(RandomUtil.randomInt(10, 100))));//生成10-100随机数corrdinate.setX(String.valueOf(RandomUtil.randomInt(10, 100)));corrdinate.setY(String.valueOf(RandomUtil.randomInt(10, 100)));//随机生成MD5corrdinate.setDesc(DigestUtils.md5Hex("hello"));list.add(corrdinate);}return list;}

@Testvoid write2(){try (ExcelWriter excelWriter = EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Corrdinate.class).build();){WriteSheet sheet2 = EasyExcel.writerSheet("Sheet2").build();WriteSheet sheet1 =EasyExcel.writerSheet("Sheet1").build();excelWriter.write(getData(10),sheet1);excelWriter.write(getData(10),sheet2);}

写入指定列

实体类

@Datapublic class Corrdinate {private long id;@ExcelProperty(value = "x",index = 1)//指定列名和顺序private String x;private String y;@ExcelProperty("是否匹配")private boolean z;@ExcelProperty("描述")private String desc;@ExcelIgnore//忽略字段private String de;}

生成数据方法

//生成数据方法private List<Corrdinate> getData(int count) {List<Corrdinate> list = ListUtils.newArrayList();for (int i = 0; i < count; i++) {Corrdinate corrdinate = new Corrdinate();corrdinate.setId(Long.parseLong(String.valueOf(RandomUtil.randomInt(10, 100))));//生成10-100随机数corrdinate.setX(String.valueOf(RandomUtil.randomInt(10, 100)));corrdinate.setY(String.valueOf(RandomUtil.randomInt(10, 100)));//随机生成MD5corrdinate.setDesc(DigestUtils.md5Hex("hello"));corrdinate.setDe(DigestUtils.md5Hex("de"));list.add(corrdinate);}return list;}

写测试

@Testvoid writeColumn(){Set<String> set = new TreeSet<>();set.add("de");EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Corrdinate.class).excludeColumnFieldNames(set).sheet("Sheet2")//指定工作簿.doWrite(getData(10));//写入10个数据}

多级列名

实体类

@Datapublic class Corrdinate {private long id;@ExcelProperty(value = "x",index = 1)//指定列名和顺序private String x;private String y;@ExcelProperty({"一级列名","是否匹配"})private boolean z;@ExcelProperty({"一级列名","描述"})private String desc;//@ExcelIgnore//忽略字段//设置一级列名,二级列名@ExcelProperty({"一级列名","二级列名"})private String de;}

写测试

@Testvoid writeDemo(){EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Corrdinate.class).sheet("Sheet3")//指定工作簿.doWrite(getData(10));//写入10个数据}

自定义格式转换 日期,数字-Write

实体类

@Datapublic class man {@ExcelProperty(converter = StringConverterString.class)private String name;@ExcelProperty("日期")@DateTimeFormat("yyyy年mm月dd日")private Date date;@NumberFormat("#.##%")private BigDecimal successrate;}

生成数据并测试写入

//生成数据方法private List<Man> getData2(int count) {List<Man> list = ListUtils.newArrayList();for (int i = 0; i < count; i++) {Man m = new Man();m.setName("张三"+i);m.setSuccessrate(BigDecimal.valueOf(RandomUtil.randomDouble(0.0, 1)));m.setDate(new Date());list.add(m);}return list;
}@Testvoid writeDemo(){EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Man.class).sheet("Sheet3")//指定工作簿.doWrite(getData2(10));//写入10个数据}}

自定义转换器-Write

自定义转换器

public class StringConverterString implements Converter<String> {//支持java类型@Overridepublic Class<?> supportJavaTypeKey() {return String.class;}//支持Excel单元格类型@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}//读的数据符合类型@Overridepublic String convertToJavaData(ReadConverterContext<?> context) throws Exception {//转换return "姓名:"+context.getReadCellData().getStringValue();}//写的数据符合类型@Overridepublic WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) throws Exception {return new WriteCellData<>("写入数据"+context.getValue());}}

生成数据并测试写入

private List<Man> getData2(int count) {List<Man> list = ListUtils.newArrayList();for (int i = 0; i < count; i++) {Man m = new Man();m.setName("张三"+i);m.setSuccessrate(BigDecimal.valueOf(RandomUtil.randomDouble(0.0, 1)));m.setDate(new Date());list.add(m);}return list;}@Testvoid writeDemo(){EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Man.class).sheet("Sheet3")//指定工作簿.doWrite(getData2(10));//写入10个数据}

指定列宽行高

@Data@HeadRowHeight(30)// 指定列头行高度@ContentRowHeight(15)// 指定内容行高度@ColumnWidth(12)//指定列宽public class Man {@ExcelProperty(converter = StringConverterString.class)private String name;@ExcelProperty("日期")@DateTimeFormat("yyyy年mm月dd日")private Date date;@NumberFormat("#.##%")private BigDecimal successrate;}

批量写入excel方法

编写实体类

@TableName(value ="product")

@Data

@NoArgsConstructor

@AllArgsConstructor

public class Product implements Serializable {

    /**

     * 序号

     */

    @TableId(type = IdType.AUTO)

    @ExcelProperty("序号")

    private Integer number;

    /**

     * 创建时间

     */

    @ExcelProperty("创建时间")

    private Date createtime;

    /**

     * 产品名称

     */

    @ExcelProperty("产品名称")

    private String productname;

    /**

     * 产品编号

     */

    @ExcelProperty("产品编号")

    private String productnumber;

    /**

     * 产品型号

     */

    @ExcelProperty("产品型号")

    private String manufacturer;

    /**

     * 产品位置

     */

    @ExcelProperty("产品位置")

    private String producepath;

    /**

     * 图片位置

     */

    @ExcelProperty("图片位置")

    private String imagepath;

    /**

     * 使用单位

     */

    @ExcelProperty("使用单位")

    private String unit;

    /**

     * 金额

     */

    @ExcelProperty("金额")

    private Integer money;

    /**

     * 入库时间

     */

    @ExcelProperty("入库时间")

    private Date intime;

    /**

     * 出库时间

     */

    @ExcelProperty("出库时间")

    private Date puttime;

    /**

     * 操作人

     */

    @ExcelProperty("操作人")

    private String operator;

    /**

     * 创建人

     */

    @ExcelProperty("创建人")

    private String createduser;

    /**

     * 备注

     */

    @ExcelProperty("备注")

    private String notes;

    /**

     * 产品数量

     */

    @ExcelProperty("产品数量")

    private Integer producedigit;

    /**

     * 产品单位

     */

    @ExcelProperty("产品单位")

    private String productunit;

    @TableField(exist = false)

    private static final long serialVersionUID = 1L;

}

//重复多次写入(写到单个或者多个Sheet)@Testpublic void manyWrite() {// 方法1: 如果写到同一个sheetString fileName = "C:\\Users\\13631\\Desktop\\simpleWriteTest1702391756908.xlsx";// 这里 需要指定写用哪个class去写try (ExcelWriter excelWriter = EasyExcel.write(fileName, Product.class).build()) {// 这里注意 如果同一个sheet只要创建一次WriteSheet writeSheet = EasyExcel.writerSheet("测试").build();long star = System.currentTimeMillis();// 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来for (int i = 0; i < 5; i++) {// 分页去数据库查询数据 这里可以去数据库查询每一页的数据List<Product> data = getData(1000);excelWriter.write(data, writeSheet);}long end = System.currentTimeMillis();System.out.println("耗时:" + (end - star)/1000 + "秒");}

自定义模板写入excel

填充单行

填充集合

//根据模板填充数据
@Test
public void fillWrite() {// 方案2 分多次 填充 会使用文件缓存(省内存)String fileName = "C:\\Users\\13631\\Desktop\\模板写数据.xlsx";String templateFileName = "C:\\Users\\13631\\Desktop\\模板.xlsx";try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {WriteSheet writeSheet = EasyExcel.writerSheet().build();excelWriter.fill(getData2(100), writeSheet);}
}

填充效果

自定义监听器

1、实体类(如上述实体类)

2、自定义监听器

Invoke和doAfterAllAnalysed是必选的

public class MyListener implements ReadListener<Product> {private TestMapper testMapper;private ArrayList<Product> list = new ArrayList<>();int sum=0;public MyListener(TestMapper testMapper) {this.testMapper = testMapper;}//每读一行,则调用该方法@Overridepublic void invoke(Product product, AnalysisContext analysisContext) {sum++;list.add(product);}//每读完整个excel,则调用该方法@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {System.out.println("读取了"+sum+"行数据");}
}
@Test
void contextLoads() {String fileName = "C:\\Users\\13631\\Desktop\\simpleWriteTest1702391756908.xlsx";// 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行// 具体需要返回多少行可以在`PageReadListener`的构造函数设置ExcelReader reader = EasyExcel.read(fileName, Product.class, new MyListener(new TestMapper())).build();ReadSheet sheet = EasyExcel.readSheet().build();reader.read(sheet);
}

Web上传下载

web中的读(上传)

后端

//上传

//上传

    @PostMapping("/upload")

    @ResponseBody

    public String upload(MultipartFile file) throws IOException {

        long start = System.currentTimeMillis();

        EasyExcel.read(file.getInputStream(), Product.class, new MyListener(productService)).sheet().doRead();

        long end = System.currentTimeMillis();

        System.out.println("耗时:"+(end-start)/1000+"秒");

        return "success";

    }

前端(vue2+Element)

<el-upload

  class="upload-demo"

  action="http://192.168.1.8:8007/excel/upload"

  :on-preview="handlePreview"

  :on-remove="handleRemove"

  :before-remove="beforeRemove"

  multiple

  :limit="3"

  :on-exceed="handleExceed"

  :file-list="fileList">

  <el-button size="small" type="primary">点击上传</el-button>

</el-upload>

效果

web中的写(下载)

后端

@GetMapping("download")public void download(HttpServletResponse response) throws IOException {// 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postmanresponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");EasyExcel.write(response.getOutputStream(), Product.class).sheet("模板").doWrite(productService.list());}

前端

<button @click="download">导出Excel</button>methods:{download(){document.location.href="http://192.168.1.8:8007/excel/download";}},

效果

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW在动态力传感器校准技术的创新应用

简介 动态力传感器校准装置集成了冲击法原理和自动化控制&#xff0c;实现精准、高效的传感器校验。LabVIEW的图形化界面提供简便操作和实时数据分析&#xff0c;显著提高了校准过程的准确度和效率。 01 系统设计和功能 动态力传感器在工业生产中发挥着重要作用&#xff0c;…

Docker 安装部署

1、Docker 安装 ① 卸载docker&#xff0c;清空之前的docker文件 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine \docker-ce…

数据库创建表并插入数据练习题

一、创建表的要求 创建一个英雄表(hero) 主键 name nickname address groups email telphone 二、 操作步骤 1.登录MySQL [rootlocalhost ~]# systemctl start mysqld [rootlocalhost ~]# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with…

【网络安全】【密码学】【北京航空航天大学】实验三、数论基础(下)【C语言实现】

实验三、数论基础&#xff08;下&#xff09; 一、实验内容 1、中国剩余定理&#xff08;Chinese Remainder Theorem&#xff09; &#xff08;1&#xff09;、算法原理 m1, m2, … mk 是一组两两互素的正整数&#xff0c;且 M m1 m2 … mk 为它们的乘积, 则如下的同余…

使用new pm写一个pass

范例来自LLVM Techniques, Tips, and Best Practices Clang and Middle-End Libraries llvm ir到ir是由一个个pass处理的&#xff0c;从一个ir到另一个ir会改变一些东西 书里面就是说想要给指针变量添加一个noalias属性 书里面使用插件的形式&#xff0c;但是不知道怎么我搞不…

MetaGPT前期准备与快速上手

大家好&#xff0c;MetaGPT 是基于大型语言模型&#xff08;LLMs&#xff09;的多智能体协作框架&#xff0c;GitHub star数量已经达到31.3k。 接下来我们聊一下快速上手 这里写目录标题 一、环境搭建1.python 环境2. MetaGpt 下载 二、MetaGPT配置1.调用 ChatGPT API 服务2.简…

手机扫一扫文档、证件表格就能打印,不用专门找扫描软件啦

现在各大品牌的手机扫一扫功能都可以满足扫描文档、扫描表格的功能&#xff0c;平常如果需要将纸质文件扫描成电子档&#xff0c;拿起手机就可以实现。文件签名后再扫描成PDF版本&#xff0c;相信大家都用得不少了。 今天就用华为手机的扫一扫给大家示范一下如何将文档、证件、…

设计模式—行为型模式之状态模式

设计模式—行为型模式之状态模式 状态&#xff08;State&#xff09;模式&#xff1a;对有状态的对象&#xff0c;把复杂的“判断逻辑”提取到不同的状态对象中&#xff0c;允许状态对象在其内部状态发生改变时改变其行为。 状态模式包含以下主要角色&#xff1a; 环境类&am…

Kafka配置Kerberos安全认证及与Java程序集成

Background 本文主要介绍在 Kafka 中如何配置 Kerberos 认证&#xff0c;以及 java 使用 JAAS 来进行 Kerberos 认证连接。本文演示为单机版。 所用软件版本 查看 Kerberos 版本命令&#xff1a;klist -V 软件名称版本jdk1.8.0_202kafka2.12-2.2.1kerberos1.15.1 1、Kerberos …

【STM32】STM32学习笔记-串口发送和接收(27)

00. 目录 文章目录 00. 目录01. 串口简介02. 串口相关API2.1 USART_Init2.2 USART_InitTypeDef2.3 USART_Cmd2.4 USART_SendData2.5 USART_ReceiveData 03. 串口发送接线图04. USB转串口模块05. 串口发送程序示例06. 串口发送支持printf07. 串口发送支持printf_v208.09.10. 01.…

Linux网络基础及bonding实际操作

1.查看linux基础的网络配置 网关&#xff1a;route -n ip地址&#xff1a;ifconfig 或 ip a DNS服务器&#xff1a;cat /etc/resolv.conf 主机名&#xff1a;hostname 路由&#xff1a;route -n 网络连接状态&#xff1a;ss 或 netstat 2.临时修改网卡名称 3.永久修…

在全志T113-i平台上实现H.265视频解码步骤详解

H.265&#xff0c;也被称为HEVC(HighEfficiency Video Coding)&#xff0c;作为H.264的继任者&#xff0c;提供了更好的视频压缩和更高的视频质。H.265通过引入更多先进的编码技术&#xff0c;如更强大的运动估计和更高效的变换编码&#xff0c;对比H.264进行了改进。这些改进使…