【Java】轻量Excel读写框架JXL学习
参考黑马教程:
https://www.bilibili.com/video/BV1eA41157va?p=5
写着写着发现有更好的Demo案例:
https://cloud.tencent.com/developer/article/1966065
所需依赖:
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>1.27</version> <!-- 请检查并使用最新版本 -->
</dependency> <dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
Excel输出API常见方法:
@SneakyThrows
public void downloadXlsByJxl(HttpServletResponse response) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
ServletOutputStream outputStream = response.getOutputStream(); /* 基于输出流创建一个新的工作簿 */
WritableWorkbook workbook = Workbook.createWorkbook(outputStream);
WritableSheet sheet = workbook.createSheet("第一个工作表", 0); /* 创建标题行 */
List<String> titleList = Arrays.asList("编号", "姓名", "手机号", "入职日期", "现在地址"); /* 创建列宽配置 */
int standardCharWidth = 1;
int chineseCharWidth = 3;
List<Integer> columnWidthSets = Arrays.asList(
standardCharWidth * chineseCharWidth * 2,
standardCharWidth * chineseCharWidth * 3,
standardCharWidth * standardCharWidth * 12,
standardCharWidth * 12,
standardCharWidth * standardCharWidth * 20); Label eachLabel = null;
for (int columnIdx = 0; columnIdx < titleList.size(); columnIdx++) {
String title = titleList.get(columnIdx);
eachLabel = new Label(columnIdx, 0, title);
sheet.addCell(eachLabel); /* 列宽设置, 列下表, 一个标准字母的宽度 */
sheet.setColumnView(columnIdx, columnWidthSets.get(columnIdx));
} List<User> allUserList = userMapper.selectAll();
for (int recordIdx = 0, rowIdx = 1; recordIdx < allUserList.size(); recordIdx ++, rowIdx ++) {
User user = allUserList.get(recordIdx);
eachLabel = new Label(0, rowIdx, String.valueOf(user.getId()));
sheet.addCell(eachLabel); eachLabel = new Label(1, rowIdx, user.getUserName());
sheet.addCell(eachLabel); eachLabel = new Label(2, rowIdx, user.getPhone());
sheet.addCell(eachLabel); eachLabel = new Label(3, rowIdx, sdf.format(user.getHireDate()));
sheet.addCell(eachLabel); eachLabel = new Label(4, rowIdx, user.getAddress());
sheet.addCell(eachLabel);
} /* 写入图片 非图片文件无法写入 Warning: Image type doc not supported. Supported types are png */
File file = new File("C:\\Users\\Administrator\\Pictures\\AngelLegionPhoto\\Girl_20240303155025.png");
WritableImage writableImage = new WritableImage(10, 10, 1, 1, file);
sheet.addImage(writableImage); /* 写入链接 */
WritableHyperlink writableHyperlink = new WritableHyperlink(10, 11, new URL("https://www.bilibili.com/video/BV1eA41157va"));
sheet.addHyperlink(writableHyperlink);
writableHyperlink = new WritableHyperlink(10, 12, new File("D:\\迅雷下载\\20121015120541355.doc"));
sheet.addHyperlink(writableHyperlink); String fileName = "JXL-Demo.xls";
response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes(), StandardCharsets.ISO_8859_1));
response.setContentType("application/vnd.ms-excel"); workbook.write();
workbook.close();
outputStream.close();
}
输出结果:
Excel读取常见API:
获取存在记录的单元格的边界列和行
能满足图片,公式,普通值的获取
@SneakyThrows
public void readXlsByJxl(MultipartFile multipartFile) {
InputStream inputStream = multipartFile.getInputStream();
Workbook workbook = Workbook.getWorkbook(inputStream);
Sheet sheet = workbook.getSheet(0);
int[] columnPageBreaks = sheet.getColumnPageBreaks();
int[] rowPageBreaks = sheet.getRowPageBreaks();
int columns = sheet.getColumns();
int rows = sheet.getRows();
int numberOfImages = sheet.getNumberOfImages();
Hyperlink[] hyperlinks = sheet.getHyperlinks();
log.info("columnPageBreaks {}", Arrays.toString(columnPageBreaks));
log.info("rowPageBreaks {}", Arrays.toString(rowPageBreaks));
log.info("columns {}", columns);
log.info("rows {}", rows);
log.info("numberOfImages {}", numberOfImages);
for (int rowIdx = 0; rowIdx < rows; rowIdx++) {
StringBuilder currentRow = new StringBuilder();
for (int colIdx = 0; colIdx < columns; colIdx++) {
Cell cell = sheet.getCell(colIdx, rowIdx);
CellType type = cell.getType();
String contents = cell.getContents();
currentRow.append("type ").append(type.toString()).append(" ,").append(contents).append(" |");
}
log.info("cell -> {}", currentRow);
}
/* 读取图片 */
if (0 != numberOfImages) {
for (int i = 0; i < numberOfImages; i++) {
Image image = sheet.getDrawing(i);
File imageFile = image.getImageFile();
String name = imageFile.getName();
double column = image.getColumn();
double row = image.getRow();
byte[] imageData = image.getImageData();
Tika tika = new Tika();
/* 图片是准确的mimeType, 非图片只能识别为octStream */
String detect = tika.detect(imageData);
log.info("image -> idx {}, {} - {}, {}, {}", i, (int) column, (int) row, name, detect);
}
}
for (Hyperlink hyperlink : hyperlinks) {
boolean isFile = hyperlink.isFile();
boolean isLocation = hyperlink.isLocation();
boolean isUrl = hyperlink.isURL();
log.info("isFile {}, isLocation {}, isUrl {}", isFile, isLocation, isUrl);
String path = isFile ? hyperlink.getFile().getPath() : isUrl ? hyperlink.getURL().getPath() : "internalLocation";
int column = hyperlink.getColumn();
int row = hyperlink.getRow();
log.info("hyperlink -> {}, {}", column + "," + row, path);
}
}
样例输出
columnPageBreaks null
rowPageBreaks null
columns 11
rows 16
numberOfImages 1
cell -> type Label ,编号 |type Label ,姓名 |type Label ,手机号 |type Label ,入职日期 |type Label ,现在地址 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,1 |type Label ,大一 |type Label ,13800000001 |type Label ,2001-01-01 |type Label ,北京市西城区宣武大街1号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,2 |type Label ,不二 |type Label ,13800000002 |type Label ,2002-01-02 |type Label ,北京市西城区宣武大街2号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,3 |type Label ,张三 |type Label ,13800000003 |type Label ,2003-03-03 |type Label ,北京市西城区宣武大街3号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,4 |type Label ,李四 |type Label ,13800000004 |type Label ,2004-02-04 |type Label ,北京市西城区宣武大街4号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,5 |type Label ,王五 |type Label ,13800000005 |type Label ,2005-03-05 |type Label ,北京市西城区宣武大街5号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,6 |type Label ,赵六 |type Label ,13800000006 |type Label ,2006-04-06 |type Label ,北京市西城区宣武大街6号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,7 |type Label ,沈七 |type Label ,13800000007 |type Label ,2007-06-07 |type Label ,北京市西城区宣武大街7号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,8 |type Label ,酒八 |type Label ,13800000008 |type Label ,2008-07-08 |type Label ,北京市西城区宣武大街8号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,9 |type Label ,第九 |type Label ,13800000009 |type Label ,2009-03-09 |type Label ,北京市西城区宣武大街9号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,10 |type Label ,石十 |type Label ,13800000010 |type Label ,2010-07-10 |type Label ,北京市西城区宣武大街10号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,11 |type Label ,肖十一 |type Label ,13800000011 |type Label ,2011-12-11 |type Label ,北京市西城区宣武大街11号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Label ,https://www.bilibili.com/video/BV1eA41157va |
cell -> type Label ,12 |type Label ,星十二 |type Label ,13800000012 |type Label ,2012-05-12 |type Label ,北京市西城区宣武大街12号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Label ,D:\迅雷下载\20121015120541355.doc |
cell -> type Label ,13 |type Label ,钗十三 |type Label ,13800000013 |type Label ,2013-06-13 |type Label ,北京市西城区宣武大街13号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,14 |type Label ,贾十四 |type Label ,13800000014 |type Label ,2014-06-14 |type Label ,北京市西城区宣武大街14号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
cell -> type Label ,15 |type Label ,甄世武 |type Label ,13800000015 |type Label ,2015-06-15 |type Label ,北京市西城区宣武大街15号院 |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |type Empty , |
image -> idx 0, 10 - 9, Girl_20240303155025.png, image/png
isFile false, isLocation false, isUrl true
hyperlink -> 10,11, /video/BV1eA41157va
isFile true, isLocation false, isUrl false
hyperlink -> 10,12, D:\迅雷下载\2012
【Java】轻量Excel读写框架JXL学习的更多相关文章
- 轻量的web框架Bottle
简洁的web框架Bottle 简介 Bottle是一个非常简洁,轻量web框架,与django形成鲜明的对比,它只由一个单文件组成,文件总共只有3700多行代码,依赖只有python标准库.但是麻雀虽 ...
- Nancy总结(一)Nancy一个轻量的MVC框架
Nancy是一个基于.net 和Mono 构建的HTTP服务框架,是一个非常轻量级的web框架. 设计用于处理 DELETE, GET, HEAD, OPTIONS, POST, PUT 和 PATC ...
- 轻量型ORM框架Dapper的使用
在真实的项目开发中,可能有些人比较喜欢写SQL语句,但是对于EF这种ORM框架比较排斥,那么轻量型的Dapper就是一个不错的选择,即让你写sql语句了,有进行了关系对象映射.其实对于EF吧,我说下我 ...
- OSCHina技术导向:Java轻量web开发框架——JFinal
JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful.在拥有Java语言所有优势的同时再拥有ru ...
- win8.1 cygwin编译java轻量虚拟机avian
1.背景 昨天在网上看到别人用aauto写本地小程序写的很爽,我觉得如果java的jre能小一点,凭借java庞大的第三方类库写小工具也还算不错的.本人就经常用eclipse+一些commons包写些 ...
- 开源 , KoobooJson一款高性能且轻量的JSON框架
KoobooJson - 更小更快的C# JSON序列化工具(基于表达式树构建) 在C#领域,有很多成熟的开源JSON框架,其中最著名且使用最多的是 Newtonsoft.Json ,然而因为版本迭代 ...
- Prism-超轻量的开源框架
http://msdn.microsoft.com/en-us/library/ff648465.aspx prism 是微软模式与实践小组开发的一个进行MVVM模式开发,其中使用依赖注入等一些方法将 ...
- 之前项目使用的轻量的goweb框架
技术栈 go 主开发语言 基于 gorilla 项目 javascript(nodejs) 部分小工具,josn对象转换,自动编译 C#,codesmith通用代码生成,生成最基本的crud和翻页. ...
- Droplet——一款轻量的Golang应用层框架
Github地址 如标题所描述的,Droplet 是一个 轻量 的 中间层框架,何为中间层呢? 通常来说,我们的程序(注意这里我们仅仅讨论程序的范围,而非作为一个系统,因此这里不设计如 LB.Gate ...
- Java学习---Excel读写操作
1.1.1. 简介 Apache POI 使用Apache POI 完成Excel读写操作 Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API ...
随机推荐
- mescroll.js 使用
mescroll.js 使用 附:点击查看中文文档 第一步:引入css和js // unpkg的CDN: <link rel="stylesheet" href=" ...
- Grafana监控系统的构建与实践
本文深入探讨了Grafana的核心技术.数据源集成.仪表盘与可视化构建以及监控与告警配置,旨在为专业从业者提供全面的Grafana技术指南. 关注[TechLeadCloud],分享互联网架构.云服务 ...
- 主成分分析(PCA)介绍
目录 计算过程 投影分量计算 假设你有一家理发店,已经记录了过去一年中所有顾客的头发长度和发型偏好的数据.现在你想从这些数据中提取一些主要的信息,比如顾客最常选择的发型类型,以及不同发型之间的相关性等 ...
- react多级路由 重定向与404定义
在有一些功能中,往往请求地址的前缀是相同的,不同的只是后面一部份,此时就可以使用多级路由(路由嵌套)来实现此路由的定义实现. 例: 路由规则如下 admin/index admin/user 它们路由 ...
- Stable Diffusion 解析:探寻 AI 绘画背后的科技神秘
AI 绘画发展史 在谈论 Stable Diffusion 之前,有必要先了解 AI 绘画的发展历程. 早在 2012 年,华人科学家吴恩达领导的团队训练出了当时世界上最大的深度学习网络.这个网络能够 ...
- 华擎 asrock b365m itx win7蓝牙播放音乐爆音
华擎 asrock b365m itx win7蓝牙播放音乐爆音,吱吱吱的杂音. 偶然间,系统换成WIN10后,再用蓝牙耳机听歌,则正常.机箱位置不变.
- CPU的一、二、三级缓存的区别
引言 概念 缓存大小也是CPU的重要指标之一,而且缓存的结构和大小对CPU速度的影响非常大,CPU内缓存的运行频率极高,一般是和处理器同频 运作,工作效率远远大于系统内存和硬盘.实际工作时,CPU往往 ...
- 在线Bcrypt加密、验证工具
在线bcrypt加密,bcrypt算法是一种密码哈希算法,它是基于Blowfish加密算法改进的,能够生成安全性很高的哈希值,并且可以通过调整计算时间来提高安全性.本工具支持在线Bcrypt加密及验证 ...
- 如果redis没有设置expire,他是否默认永不过期
如果redis没有设置expire,他是否默认永不过期?默认是的 通过EXPIRE key seconds 命令来设置数据的过期时间.返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间 ...
- OpenCompass 作业
Smiling & Weeping ---- 愿我们都做生活的高手 -- 昭阳&乐瑶