当前位置: 首页 > news >正文

Spring Boot 与 EasyExcel 携手:复杂 Excel 表格高效导入导出实战

数据的并行导出与压缩下载:EasyExcel:实现大规模数据的并行导出与压缩下载

构建高效排队导出:解决多人同时导出Excel导致的服务器崩溃

SpringBoot集成EasyExcel 3.x:

前言

在企业级应用开发中,常常需要处理复杂的 Excel 表格数据。本方案将 Spring Boot 强大的后端框架与 EasyExcel 这一高效的 Excel 处理工具进行整合,实现了复杂 Excel 表格的导入与导出功能。

对于导入功能,能够轻松应对包含多种数据类型、复杂结构以及大量数据的 Excel 文件。通过合理的配置和处理流程,确保数据的准确性和完整性,将 Excel 中的数据快速导入到系统中,为后续的数据处理和业务逻辑提供有力支持。

在导出方面,能够根据系统中的数据生成结构复杂、格式规范的 Excel 表格。可以自定义表头、样式、格式等,满足不同业务场景下对 Excel 报表的需求。无论是生成详细的业务数据报表,还是复杂的统计分析结果,都能通过这个整合方案轻松实现。

组件介绍

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

Alibaba EasyExcel的核心类是EasyExcel类。

案例

1、简单的读操作

/*** 最简单的读* 1. 创建excel对应的实体对象 参照{@link DemoData}* 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}* 3. 直接读即可*/
@Test
public void simpleRead() {String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();
}

2、简单的写操作

/*** 最简单的写* 1. 创建excel对应的实体对象 参照{@link com.alibaba.easyexcel.test.demo.write.DemoData}* 2. 直接写即可*/
@Test
public void simpleWrite() {String fileName = TestFileUtil.getPath() + "write" + System.currentTimeMillis() + ".xlsx";// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭// 如果这里想使用03 则 传入excelType参数即可EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
}

项目基本信息

一、单个sheet&表头合并

1、添加pom.xml依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.1</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>SpringBoot-easyexcel</artifactId><version>0.0.1-SNAPSHOT</version><name>SpringBoot-easyexcel</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><!-- Web组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- easyexcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency><!-- commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version></dependency><!-- lombok插件 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
2. 创建数据模型

创建一个数据模型类,用于表示Excel中的一行数据。例如,我们有一个包含用户信息的复杂Excel表格:

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.metadata.data.WriteCellData;
import lombok.Builder;
import lombok.Data;import java.util.Date;@Data
@Builder
public class UserData{@ExcelProperty(value = "用户ID", index = 0)@ColumnWidth(10)private Long userId;@ExcelProperty(value = "用户名称", index = 1)@ColumnWidth(10)private String userName;@ExcelProperty(value = {"基本信息", "手机号码"}, index = 2)@ColumnWidth(20)private String userPhone;@ExcelProperty(value = {"基本信息", "电子邮箱"}, index = 3)@ColumnWidth(20)private String userEmail;@ExcelProperty(value = {"基本信息", "地址"}, index = 4)@ColumnWidth(20)private String userAddress;@ExcelProperty(value = "注册时间", index = 5)@ColumnWidth(20)private Date registerTime;@ExcelProperty(value = "性别,男:红色/女:绿色")@ColumnWidth(30)private WriteCellData<String> gender;/*** 忽略这个字段*/@ExcelIgnoreprivate Integer age;
}
3. 创建导出服务

创建一个服务类,用于实现Excel的导出功能:

import com.alibaba.excel.EasyExcel;  
import org.springframework.stereotype.Service;  import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;  
import java.net.URLEncoder;  
import java.util.List;  @Service  
public class ExcelExportService {  public void exportUsers(List<UserData> userDataList, HttpServletResponse response) throws IOException {  // 设置响应类型response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");// 设置编码格式response.setCharacterEncoding("utf-8");// 设置URLEncoder.encode 防止中文乱码String fileName = URLEncoder.encode("信息表", "UTF-8").replaceAll("\\+", "%20");// 设置响应头response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");EasyExcel.write(response.getOutputStream(), UserData.class).inMemory(true).sheet("用户信息表").doWrite(userDataList);}private static WriteCellData<String> buildCellData(String gender) {// 设置单个单元格多种样式WriteCellData<String> cellData = new WriteCellData<>();// 设置单个单元格的填充类型cellData.setType(CellDataTypeEnum.RICH_TEXT_STRING);RichTextStringData richTextStringData = new RichTextStringData();cellData.setRichTextStringDataValue(richTextStringData);richTextStringData.setTextString(gender);WriteFont writeFont = new WriteFont();if ("男".equalsIgnoreCase(gender)) {//设置颜色为红色writeFont.setColor(IndexedColors.RED.getIndex());} else if ("女".equalsIgnoreCase(gender)) {//设置颜色为绿色writeFont.setColor(IndexedColors.GREEN.getIndex());}//应用颜色字体richTextStringData.applyFont(writeFont);return cellData;}  
}
4. 创建导入服务

导入的数据模型

import java.util.Date;import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.metadata.data.WriteCellData;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;@Data
@Builder
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class UserData {private Long userId;private String userName;private Integer age;private String userPhone;private String userEmail;private String userAddress;private Date registerTime;private String gender;
}

创建一个服务类,用于实现Excel的导入功能:

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;@Slf4j
@Service
public class ExcelImportService {/*** 每隔一定数量的数据存储到数据库,可根据实际情况调整。*/private static final int BATCH_COUNT = 100;/*** 手机号正则表达式校验。*/private static final Pattern PHONE_REGEX = Pattern.compile("^1[0-9]{10}$");/*** 缓存要导入的数据列表。*/private List<UserData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/*** 错误信息列表。*/private final List<String> errorMsgList = new ArrayList<>();// 假设这里有一个数据访问层的接口引用private UserDataRepository userDataRepository;public ExcelImportService(UserDataRepository userDataRepository) {this.userDataRepository = userDataRepository;}/*** 导入 Excel 文件并保存数据到数据库。** @param excelFilePath Excel 文件路径。*/public void importExcel(String excelFilePath) {EasyExcel.read(excelFilePath, UserData.class, new CustomAnalysisEventListener()).sheet().doRead();}class CustomAnalysisEventListener extends AnalysisEventListener<UserData> {@Overridepublic void invoke(UserData userData, AnalysisContext analysisContext) {log.info("解析到一条数据:{}", userData);int rowIndex = analysisContext.readRowHolder().getRowIndex();String name = userData.getUserName();String phone = userData.getUserPhone();String gender = userData.getGender();String email = userData.getUserEmail();Integer age = userData.getAge();String address = userData.getUserAddress();// 只有全部校验通过的对象才能被添加到下一步if (nameValid(rowIndex, name) && phoneValid(rowIndex, phone) && genderValid(rowIndex, gender) &&emailValid(rowIndex, email) && ageValid(rowIndex, age) && addressValid(rowIndex, address)) {cachedDataList.add(userData);}// 达到 BATCH_COUNT 了,存储到数据库并清理列表if (cachedDataList.size() >= BATCH_COUNT) {saveDataToDatabase();cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {log.info("所有数据解析完成!全部校验通过的数据有{}条", cachedDataList.size());// 保存剩余数据到数据库saveDataToDatabase();}@Overridepublic void onException(Exception exception, AnalysisContext context) throws Exception {if (exception instanceof RuntimeException) {throw exception;}int index = context.readRowHolder().getRowIndex() + 1;errorMsgList.add("第" + index + "行解析错误");}@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {int totalRows = context.readSheetHolder().getApproximateTotalRowNumber() - 1;int maxNum = 2000;if (totalRows > maxNum) {errorMsgList.add("数据量过大,单次最多上传2000条");throw new RuntimeException("数据量过大,单次最多上传2000条");}}}/*** 将缓存的数据保存到数据库。*/private void saveDataToDatabase() {userDataRepository.saveAll(cachedDataList);}public List<String> getErrorMsgList() {return errorMsgList;}/*** 名称的校验。** @param rowIndex 行数。* @param name     名称。*/private Boolean nameValid(Integer rowIndex, String name) {if (StringUtils.isBlank(name)) {errorMsgList.add("第" + rowIndex + "行,'姓名'不能为空");return false;}return true;}/*** 手机号的校验。** @param rowIndex 行数。* @param phone    手机号。*/private Boolean phoneValid(int rowIndex, String phone) {if (StringUtils.isBlank(phone)) {errorMsgList.add("第" + rowIndex + "行,'手机号'不能为空");return false;}return true;}/*** 性别的校验。** @param rowIndex 行数。* @param gender   性别。*/private Boolean genderValid(int rowIndex, String gender) {if (StringUtils.isBlank(gender)) {errorMsgList.add("第" + rowIndex + "行,'性别'不能为空");return false;}return true;}/*** 地址的校验。** @param rowIndex 行数。* @param address  地址。*/private Boolean addressValid(int rowIndex, String address) {// 校验地址是否为空if (StringUtils.isBlank(address)) {errorMsgList.add("第 " + rowIndex + " 行,'地址'不能为空");return false;}return true;}/*** 年龄的校验。** @param rowIndex 行数。* @param age      年龄。*/private Boolean ageValid(int rowIndex, Integer age) {// 校验年龄是否为空if (Objects.isNull(age)) {errorMsgList.add("第 " + rowIndex + " 行'年龄'不能为空");return false;}return true;}/*** 邮箱的校验。** @param rowIndex 行数。* @param email    邮箱。*/private Boolean emailValid(int rowIndex, String email) {// 校验邮箱是否为空if (StringUtils.isBlank(email)) {errorMsgList.add("第 " + rowIndex + " 行'邮箱'不能为空");return false;}return true;}
}
5. 创建控制器

创建一个控制器类,用于处理Excel的导入与导出请求:

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.web.bind.annotation.*;  
import org.springframework.web.multipart.MultipartFile;  import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;  
import java.util.List;  @RestController  
@RequestMapping("/excel")  
public class ExcelController {  @Autowired  private ExcelExportService excelExportService;  @Autowired  private ExcelImportService excelImportService;@Autowired  private UserService userService;  @GetMapping("/export")  public void exportUsers(HttpServletResponse response,  @RequestParam(value = "data", required = false) List<UserData> userDataList) throws IOException { // 判断userDataList是否为空,为空就去数据库查询数据,后执行导出操作 if (userDataList == null || userDataList.isEmpty()) {  // 从数据库或其他地方获取数据  userDataList = userService.findAll();for (UserData userData: userDataList) {// 修改性别单元格的样式excelExportService.buildCellData(userData.getGender)}  }excelExportService.exportUsers(userDataList, response);  }  @PostMapping("/import")  public String importUsers(@RequestParam("file") MultipartFile file) {  try {  String filePath = "/path/to/upload/" + file.getOriginalFilename();  file.transferTo(new java.io.File(filePath));  excelImportService.importExcel(filePath);  return "导入成功";  } catch (Exception e) {  e.printStackTrace();  return "导入失败";  }  }  
}
6. 运行项目并测试

启动Spring Boot项目,然后你可以通过以下URL进行测试:

  • 导出Excel文件http://localhost:8080/excel/export(可以传递一个data参数,包含要导出的用户数据)

  • 导入Excel文件http://localhost:8080/excel/import(上传一个Excel文件)‘

二、多个sheet导出

1、创建数据模型

城市实体类

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Builder;
import lombok.Data;@Data
@Builder
public class City{@ExcelProperty(value = "城市名称", index = 0)@ColumnWidth(10)private String cityName;@ExcelProperty(value = "城市介绍", index = 1)@ColumnWidth(60)private String cityDesc;
}

公司实体类

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Builder;
import lombok.Data;@Data
@Builder
public class Company{@ExcelProperty(value = "公司名称", index = 0)@ColumnWidth(10)private String companyName;@ExcelProperty(value = "公司创始人", index = 1)@ColumnWidth(10)private String companyBoss;@ExcelProperty(value = "公司总基地", index = 2)@ColumnWidth(10)private String companyBase;@ExcelProperty(value = "公司简介", index = 3)@ColumnWidth(50)private String companyDesc;
}
2、创建导出服务

创建一个服务类,用于实现Excel的导出功能:

import com.alibaba.excel.EasyExcel;  
import org.springframework.stereotype.Service;  import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;  
import java.net.URLEncoder;  
import java.util.List;  @Service  
public class ExcelExportAllService {  public void exportUsers(List<UserData> userDataList,List<CityList> cityList,List<CompanyList> companyList, HttpServletResponse response) throws IOException {  // 设置响应类型response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");// 设置编码格式response.setCharacterEncoding("utf-8");// 设置URLEncoder.encode 防止中文乱码String fileName = URLEncoder.encode("信息表", "UTF-8").replaceAll("\\+", "%20");// 设置响应头response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");// 多个sheet的输出需要使用ExcelWriter类,这里想要下载成功,需要输出到OutputStream中try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).inMemory(true).build()) {// 创建用户信息表的sheet,写入用户信息数据,1代表sheet的位置是第一个WriteSheet userInfoSheet = EasyExcel.writerSheet(0, "用户信息表").head(UserData.class).build();excelWriter.write(userDataList, userInfoSheet);// 创建城市信息表的sheet,写入城市信息数据,2代表sheet的位置是第二个WriteSheet cityInfoSheet = EasyExcel.writerSheet(1, "城市信息表").head(City.class).build();excelWriter.write(cityList, cityInfoSheet);// 创建公司信息表的sheet,写入公司信息数据,3代表sheet的位置是第三个WriteSheet companyInfoSheet = EasyExcel.writerSheet(2, "公司信息表").head(Company.class).build();excelWriter.write(companyList, companyInfoSheet);}}
}
3、创建控制器

创建一个控制器类,用于处理Excel的导入与导出请求

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.web.bind.annotation.*;  
import org.springframework.web.multipart.MultipartFile;  import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;  
import java.util.List;  @RestController  
@RequestMapping("/excelAll")  
public class ExcelAllController {  @Autowired  private ExcelExportAllService excelExportAllService;  @Autowired  private UserDataService userService;@Autowired  private CompanyService companyService;  @Autowired  private CityService cityService;  @GetMapping("/export")  public void exportUsers(HttpServletResponse response,  @RequestParam(value = "userDataList", required = false) List<UserData> userDataList,@RequestParam(value = "companyList", required = false) List<Company> companyList,@RequestParam(value = "cityList", required = false) List<City> cityList) throws IOException { // 判断userDataList是否为空,为空就去数据库查询数据,后执行导出操作 if (userDataList == null || userDataList.isEmpty()) {  // 从数据库或其他地方获取数据  userDataList = userService.findAll(); }if (companyList== null || companyList.isEmpty()) {  // 从数据库或其他地方获取数据  companyList= companyService.findAll(); }if (cityList== null || cityList.isEmpty()) {  // 从数据库或其他地方获取数据  cityList= cityService.findAll(); }excelExportAllService.exportUsers(userDataList,cityList,companyList, response);  }  }
4. 运行项目并测试

启动Spring Boot项目,然后你可以通过以下URL进行测试:

  • 导出Excel文件http://localhost:8080/excelAll/export

多个sheet导出

相关文章:

Spring Boot 与 EasyExcel 携手:复杂 Excel 表格高效导入导出实战

数据的并行导出与压缩下载&#xff1a;EasyExcel&#xff1a;实现大规模数据的并行导出与压缩下载 构建高效排队导出&#xff1a;解决多人同时导出Excel导致的服务器崩溃 SpringBoot集成EasyExcel 3.x&#xff1a; 前言 在企业级应用开发中&#xff0c;常常需要处理复杂的 …...

什么是严肃游戏,严肃游戏本地化的特点是什么?

“严肃游戏”是一种交互式数字体验&#xff0c;不仅用于娱乐&#xff0c;还用于教育、培训或解决问题。与主要关注乐趣和参与度的传统游戏不同&#xff0c;严肃游戏的目标不仅仅是娱乐&#xff0c;比如教授特定技能、模拟现实生活场景或提高对重要问题的认识。它们用于医疗保健…...

ceph补充介绍

SDS-ceph ceph介绍 crushmap 1、crush算法通过计算数据存储位置来确定如何存储和检索&#xff0c;授权客户端直接连接osd 2、对象通过算法被切分成数据片&#xff0c;分布在不同的osd上 3、提供很多种的bucket&#xff0c;最小的节点是osd # 结构 osd (or device) host #主…...

2024/11/1 408 20题

b d c c a b d c c...

Python相关类库使用问题

文章目录 前言 一、pandas是什么&#xff1f; 二、使用步骤 1.引入库 2.读入数据 总结 前言 在工作中不时遇到新的需求&#xff0c;需要用到新的类库&#xff0c;以此篇专门记录Python类库使用过程中遇到的问题与解决 一、Python是什么&#xff1f; Python是一种高级编…...

ESP32/ESP8266开发板单向一对多ESP-NOW无线通信

ESP32/ESP8266开发板单向一对多ESP-NOW无线通信 简介读取ESP32/ESP8266接收方Receiver的MAC地址ESP32/ESP8266发送方Sender程序ESP32/ESP8266接收方Receiver程序ESP-NOW通信验证总结 简介 本实验通过ESP-NOW无线通信协议实现多个ESP32/ESP 8266开发板向ESP32开发板发送数据。例…...

动态规划-回文串问题——5.最长回文子串

1.题目解析 题目来源&#xff1a;5.最长回文子串——力扣 测试用例 2.算法原理 1.状态表示 判断回文子串需要知道该回文子串的首尾下标&#xff0c;所以需要一个二维数组且数据类型为bool类型来存储每个子字符串是否为回文子串&#xff0c; 即dp[i][j]:以第i个位置为起始&a…...

rtp协议:rtcp包发送和接收规则和报告!

RTCP Packet Send and Receive Rules&#xff1a; 发送和接收 RTCP 包的规则在此列出。允许在多播环境或多点单播环境中运行的实现必须满足第 6.2 节中的要求。这样的实现可以使用本节定义的算法来满足这些要求&#xff0c;或者可以使用其他算法&#xff0c;只要其性能等同或更…...

label数据(或自定义数据集)转imagenet(用于mmclassification)

理论上用于分类的图像一般都不需要用labelme来标注的&#xff0c;笔者是因为刚好手上有这么一组数据&#xff0c;所以就顺带处理了。labelme标注完的数据每张还包含了一个json文件&#xff0c;这个在分类任务中用不上。具体的mmclassification使用方法在我的另一篇文章里有&…...

WebMvcConfigurer

WebMvcConfigurer是Spring MVC框架中的一个核心接口&#xff0c;它允许开发者自定义Spring MVC的配置&#xff0c;以满足应用程序的特定需求。通过实现这个接口&#xff0c;开发者可以注册拦截器、添加视图控制器、配置视图解析器等&#xff0c;而无需使用XML配置。以下是对Web…...

Sigrity Power SI VR noise Metrics check模式如何进行电源噪声耦合分析操作指导

SSigrity Power SI VR noise Metrics check模式如何进行电源噪声耦合分析操作指导 Sigrity Power SI的VR noise Metrics check模式本质上是用来评估和观测器件的电源网络的耦合对于信号的影响,输出S参数以及列出具体的贡献值。 以下图为例...

Python+Appium+Pytest+Allure自动化测试框架-安装篇

文章目录 安装安装ADT安装NodeJs安装python安装appium安装Appium Server&#xff08;可选&#xff09;安装Appium-Inspector&#xff08;可选&#xff09;安装allure安装pytest PythonAppiumPytestAllure框架的安装 Appium是一个开源工具&#xff0c;是跨平台的&#xff0c;用于…...

Python的socket使用

在 Python 中&#xff0c;可以使用 socket 模块编写一个支持多个客户端连接的服务端。常见的实现方式包括使用多线程、多进程或异步 I/O。下面以多线程为例展示如何编写一个服务端&#xff0c;来同时接收和处理多个客户端的连接。 多线程服务端代码示例 这个示例服务端代码中…...

如何快速搭建一个3D虚拟展厅?

随着元宇宙概念的兴起&#xff0c;一个全新的虚拟、立体数字空间正逐步成为我们生活的一部分。在这个空间里&#xff0c;用户可以沉浸其中&#xff0c;进行丰富的交互操作&#xff0c;体验前所未有的无限可能。而如何快速搭建一个属于自己的元宇宙3D虚拟展厅&#xff0c;正成为…...

Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)

webview打开本地Html文件 1.在路径前面加上file:// String filePath"file://"path;webView.loadUrl( filePath);2.打开权限 <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" />3.启用JavaScript 设置本地访问权限 webVi…...

解决项目中图片出不来的bug

在页面端图片呈现割裂状&#xff1a; 查看代码&#xff1a; 将代码改成&#xff1a; 即可正常显示图片。...

手机实时提取SIM卡打电话的信令声音-新的篇章(三、Android虚拟声卡探索)

手机实时提取SIM卡打电话的信令声音-新的篇章(三、Android虚拟声卡探索) 前言 前面的篇章中&#xff0c;我们从理论方向和实际市面上出现的音频线传输声音的方式&#xff0c;讨论绕开手机对SIM卡电话通话声音的封锁场景的可行性&#xff0c;并实际选购几款数字和模拟的USB转接…...

REST APIs与微服务:关键差异

在构建基于微服务的应用程序时RESYful API和微服务这两个术语经常相伴出现。然而&#xff0c;它们指的是截然不同的东西。 了解 RESTful API 和微服务之间差异的最简单方式是这样&#xff1a; 微服务&#xff1a;它们是构成更大规模基于微服务的应用程序的单个服务和功能&…...

【网安案例学习】反向蛮力攻击Reverse Brute Force Attack

【故事一】 在一个温暖的秋日下午&#xff0c;Jack坐在旧金山一家宁静的咖啡馆里&#xff0c;准备开始他的最新写作项目&#xff1a;追溯反向蛮力攻击的起源和发展。这是一个他一直想深入挖掘的主题&#xff0c;因为它揭示了网络安全世界中一个鲜为人知却极具影响力的故事。 …...

TCP/IP网络编程:理解网络编程和套接字

TCP/IP网络编程&#xff1a;理解网络编程和套接字 网络编程又叫做套接字编程&#xff0c;是因为在网络编程中依赖使用套接字(socket),网络编程一般是C/S架构&#xff0c;即客户端/服务器模式&#xff0c;在服务器端依赖套接字绑定自身接口&#xff0c;并开启监听客户端连接&am…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...