前言:

以下内容为个人见解,勿喷,欢迎有更好解决方法的大佬指点

问题起源:

最近项目中有一个这样的需求:根据后台数据生成Excel后转存到服务器上供用户进行下载。这本来是一个比较常见的需求,不存在什么难点,但是客户要求部分数值列在Excel中展示为“数值”而非“常规”,这其实也没什么问题,但是在实现的过程中却遇到了一些坑。

问题复现:

最初实现,整体代码见文章结尾,此时设置数值格式的代码为:

//设定数字格式
//数值 保留两位小数 千分位展示
NumberFormat numberFont = new NumberFormat("#,##0.00_ ");

"#,##0.00_ "中为预期的数值展示样式,以两位小数、千分位数值型展示,但是实际生成的EXCEL中的样式却是以两位小数、千分位货币型展示。

那么问题是出在哪里?要排查这个问题,我们首先要知道设置数字样式的来源,这个样式并不是凭空编造的,而是从Excel的相关样式直接复制出来的,步骤如下:

1.首先在某个数字型单元格上右键设置单元格格式,选择数字-数值,选择小数位数,勾选千分位分割,选择数字的展示样式;

2.此时先不要点击确定,选择数字-自定义,此时类型中的一串公式“#,##0.00_ ”即为我们需要的格式,复制出来即可。

那么,理论上,我们使用JXL生成Excel时,使用这个样式的单元格的数字格式应为”数值“:

但是,实际上得到的却是”货币“,如下:

问题排查:

这是为什么呢?我们来看一下此时这个单元格的数字格式公式是什么。从下图可以看到,我们设置的是”#,##0.00_ “,而得到的却是”#,##0.00“,显而易见我们设置的公式由于某种原因”_ “(下划线和空格)都被干掉了。那么,接下来只需解决这个,让他不被干掉就行了。

既然出问题的地方是格式公式,那么我们从这里开始debug看看吧(针对版本为2.6.12)。

可以看到,在 jxl.write.biff.NumberFormatRecord 的第16行执行后,公式中的下划线和空格被干掉了。

问题处理:

找到了原因,怎么解决呢?重写这个方法?算了,先看看有没有原生的方法能用吧,然后发现了这个方法,jxl.write.NumberFormat类下的NumberFormat(String format, NonValidatingFormat dummy),可以看到该方法只是将公式中的"E0"换为"E+0",正合我用。(至于参数中的NonValidatingFormat dummy,好像没啥用吧,有懂的大佬还请不吝赐教)。


于是,之前的使用公式的代码改造成了这样:

//设定数字格式
//数值 保留两位小数 千分位展示
NumberFormat numberFont = new NumberFormat("#,##0.00_ ", null);

修改后的效果已经达到预期了,如下:

注意:

上述方法只是针对设置数值公式却展示为货币的处理方式,而且只是针对简单的数值公式,比较复杂的可能不适用(如”0.00_ ;[红色]-0.00 “、”#,##0.00_);[红色](#,##0.00)“)

源码:

JXL生成EXCEL代码

package com.codelin.demo.utils;import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.*;
import jxl.format.VerticalAlignment;
import jxl.write.Number;
import jxl.write.*;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.Boolean;
import java.util.ArrayList;
import java.util.List;/*** @author CodeLin* @date 2022/4/8 21:50*/
public class ExcelUtil {static final String excelFilePath = "D:\\excel\\测试.xls";public static void main(String[] args) throws Exception {//内容List<Account> content = new ArrayList<>();content.add(new Account("甲", 10897.21));content.add(new Account("乙", 210897.31));content.add(new Account("丙", 310897.41));content.add(new Account("丁", 410897.51));content.add(new Account("戊", 510897.61));content.add(new Account("己", 60897.71));content.add(new Account("庚", 70897.01));content.add(new Account("辛", 80897.11));generateExcel(content);}/*** 生成excel文件** @param content* @throws Exception*/private static void generateExcel(List<Account> content) throws Exception {//创建一个文件File file = createFile(excelFilePath);//创建一个输出流,读取文件OutputStream outputStream = new FileOutputStream(file);//创建一个工作簿WritableWorkbook writableWorkbook = Workbook.createWorkbook(outputStream);//创建第一个工作表  第一个参数为:工作表名称,第二个参数:第几个工作表,从0开始WritableSheet writableSheet = writableWorkbook.createSheet("账户信息", 0);//写入数据writeWorksheet(writableSheet, content);//关闭流writableWorkbook.write();writableWorkbook.close();outputStream.close();}/**** @param writableSheet* @param content* @throws Exception*/private static void writeWorksheet(WritableSheet writableSheet, List<Account> content) throws Exception {//添加表头//获取表头单元格格式  居中 黑色18号宋 灰色背景WritableCellFormat titleWcf = setWritableCellFormat(getWritableFontTitle(), Alignment.CENTRE, VerticalAlignment.CENTRE, false, Colour.GRAY_25);writableSheet.addCell(getLabel(0, 0, "账户名称", titleWcf));writableSheet.addCell(getLabel(1, 0, "账户余额", titleWcf));// 设置行的高度writableSheet.setRowView(0, 600);//添加内容//获取单元格格式  左对齐,红色9号字体WritableCellFormat textWcf = setWritableCellFormat(getWritableFont(Colour.BLACK), Alignment.LEFT, VerticalAlignment.CENTRE, false, null);WritableFont numberWritableFont = getWritableFont(Colour.BLACK);//设定数字格式//数值 保留两位小数 千分位展示NumberFormat numberFont = new NumberFormat("#,##0.00_ ", null);//单元格宽度  第几列,宽度writableSheet.setColumnView(0, 30);writableSheet.setColumnView(1, 30);for (int i = 0; i < content.size(); i++) {Account account = content.get(i);writableSheet.addCell(getLabel(0, i + 1, account.getAccountName(), textWcf));WritableCellFormat writableCellFormat = new WritableCellFormat(numberWritableFont, numberFont);//设置边框 四周 细线条 黑色writableCellFormat.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK);writableSheet.addCell(new Number(1, i + 1, account.accountBal, writableCellFormat));}}/*** 获取Label** @param col  列* @param row  行* @param cont 内容* @param wcf  格式* @return Label*/private static Label getLabel(Integer col, Integer row, String cont, CellFormat wcf) {return new Label(col, row, cont, wcf);}/*** 文本字体格式* 宋体,字号12,非粗体,非斜体,无下划线,字体颜色自定义** @return WritableFont*/private static WritableFont getWritableFont(Colour colour) {return new WritableFont(WritableFont.createFont("宋体"), 12, WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, colour);}/*** 获取表头样式* 字体格式* 宋体,字号18,粗体,非斜体,无下划线,字体颜色黑色** @return WritableFont*/private static WritableFont getWritableFontTitle() {WritableFont writableFont = new WritableFont(WritableFont.createFont("宋体"), 18, WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);return writableFont;}/*** 设置居中单元格格式** @param wf* @param alignment         水平对齐样式* @param verticalAlignment 垂直对齐样式* @param wrap              是否换行* @param background        背景色* @return* @throws WriteException*/private static WritableCellFormat setWritableCellFormat(WritableFont wf, Alignment alignment, VerticalAlignment verticalAlignment, Boolean wrap, Colour background) throws WriteException {WritableCellFormat wcf = new WritableCellFormat(wf);if (alignment != null) {// 水平居中wcf.setAlignment(alignment);}if (verticalAlignment != null) {//垂直居中wcf.setVerticalAlignment(verticalAlignment);}//设置边框 四周 细线条 黑色wcf.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK);//关闭自动换行wcf.setWrap(wrap == null ? false : wrap);if (background != null) {//设置背景色为灰色wcf.setBackground(background);}return wcf;}/*** 创建文件** @param path 路径* @return File* @throws IOException 异常*/private static File createFile(String path) throws IOException {File file = new File(path);//判断目录是否存在/不存在就创建if (!file.getParentFile().exists()) {file.getParentFile().mkdirs();}//文件存在则先删除if (file.exists()) {file.delete();}//创建文件if (!file.createNewFile()) {throw new IOException("创建文件失败");}return file;}
}class Account {String accountName;Double accountBal;public String getAccountName() {return accountName;}public void setAccountName(String accountName) {this.accountName = accountName;}public Double getAccountBal() {return accountBal;}public void setAccountBal(Double accountBal) {this.accountBal = accountBal;}Account(String accountName, Double accountBal) {this.accountName = accountName;this.accountBal = accountBal;}@Overridepublic String toString() {return "Account{" +"accountName='" + accountName + '\'' +", accountBal=" + accountBal +'}';}
}

JXL生成EXCEL时单元格设置为数值却展示货币或自定义的问题处理相关推荐

  1. jxl操作excel(合并单元格,设置背景色,字体颜色)

    现在正在做的项目中涉及大量的Excel文件导出导入操作,都是使用Java Excel来操作. Java Excel是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Exce ...

  2. js导出excel单元格内换行符代码_PHP生成excel时单元格内换行问题的解决方法

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  3. Excel单个单元格多个数值求平均值

    Excel单个单元格多个数值求平均值 标签: Excel办公求和实用单元格 办公软件相关(3) 下面例子以office2007为例操作 数据格式如下图: EVALUATE(A1) 这个是核心 1:首先 ...

  4. Excel的单元格设置下拉选项并填充颜色

    如何在Excel的单元格中加入下拉选项 方法/步骤 第一步:打开excel文档,选中需加入下拉选项的单元格. 第二步:点击菜单中的"数据"->"数据有效性" ...

  5. java用poi 生成excel并单元格,字体,样式

    1.最近根据客户需求,需要生成要求的excell 格式 索性研究了下用POI 生成这个excel的功能,poi可以合并单元格(合并列,全并行)及字体,边框等,能满足大部分格式样式,写了个简单的测试列子 ...

  6. java基于jxl获取excel合并单元格

    jxl 通过 sheet.getMergedCells()方法获取excel中合并的单元格 需注意: Sheet sheet = workbook.getSheet(sheetIndex); √ OK ...

  7. JXL导出EXCEL合并单元格、文字对齐方式 .

    public void createNoLotteryAlarmExcel(String filePath,String fileName,List<NoLotteryAlarm> ala ...

  8. JXL导出EXCEL合并单元格、文字对齐方式

    这次能做出来,主要是感谢各位在网上提供的资料,在此记录 导出的结果是,大家看哈,若有可取之处可继续 代码比较多,大家主要看哈我用红色标注部分即可 --------------------------- ...

  9. jxl操作excel单个单元格换行和获取换行

    excel中同表格换行: a+"\n"+b 1.读取 String str = sheet.getCell(c, r).getContents(); String[] split ...

最新文章

  1. java clob内存溢出_java - java.sql.SQLException:ORA-01704:字符串文字太长时插入或更新 - 堆栈内存溢出...
  2. Common FileUpload组件的简单使用
  3. java面试题2 牛客:定义类中成员变量时不可能用到的修饰是
  4. 太神奇!波士顿动力又出新视频!Spot 机器狗这次竟学会了跳绳...
  5. 互联网产品经理喜欢的内容,连张小龙都主动加微信的男人写的
  6. 三个优秀的PyTorch实现语义分割框架
  7. How to make BBED(Oracle Block Brower and EDitor Tool) on Unix/Linux/Windows
  8. 预处理_关于食材预处理
  9. CSS实现限制字数功能
  10. 单相智能电表(DL/T645-2007协议)
  11. webrtc QOS方法十二(接收端IDR帧请求)
  12. 按照账号定位持续发视频,数据不会太差!
  13. 刚上线的App该如何做好ASO优化?
  14. 如何有效提升技术[成为大Niu]的两个方法
  15. 屏幕小于6英寸的手机_来!推荐几款6英寸以内“小屏手机”给你
  16. Qt官方示例-速度仪表盘
  17. CIO要顶住词汇爆炸的冲击(转)
  18. WPS Excel采集网页的表格数据
  19. 虚拟机识别并使用串口
  20. 海思一颗料暴涨7倍,全球芯片缺货真相:原厂38颗MCU掌控汽车产业链

热门文章

  1. 数据库sql语句练习 基础篇
  2. lmk04821 0-delay模式配置
  3. Windows环境下训练OpenCV分类器
  4. java 全国电视台直播_基于JAVA的电视台直播节目时间表api调用代码实例
  5. Excel中用函数按照某字段分列取得指定字段的值
  6. 关于如何修改Intel QC7笔记本BIOS启动LOGO的保姆级教程
  7. PHP绘制正方形印章,PHP-怎样高效生成图片印章和水印?
  8. 2020年伊犁州教师职称计算机考试,关于做好2020年教师专业技术职务评聘工作的通知...
  9. 使用Topshelf定时执行操作
  10. java-php-python-ssm美容院信息管理系统计算机毕业设计