精华内容
下载资源
问答
  • php程序将数据导出excel表格时发现一个问题,若字符串过长会自动转换为科学计数法。解决此问题只需在添加excel值时拼接一个制表符 如 //值拼接制表符 $value = $value."\t"; require_once __DIR__ ....

    php程序将数据导出至excel表格时发现一个问题,若字符串过长会自动转换为科学计数法。解决此问题只需在添加excel值时拼接一个制表符

    //值拼接制表符
    $value = $value."\t";
    
    require_once __DIR__ . '/./PHPExcel/Classes/PHPExcel.php';
    require_once __DIR__ . '/./PHPExcel/Classes/PHPExcel/IOFactory.php';
    require_once __DIR__ . '/./PHPExcel/Classes/PHPExcel/Writer/Excel5.php';
    require_once __DIR__ . '/./PHPExcel/Classes/PHPExcel/Writer/Excel2007.php';
    $objReader = PHPExcel_IOFactory::createReader("Excel5");
    $url = './1.xls';
    $objPHPExcel = $objReader->load($url);
    $sheet = $objPHPExcel->getSheet(0);
    $sheet->getCellByColumnAndRow(1,0)->setValue($value);

     

    展开全文
  • Java导出excel表格 表格内的数字四舍五入保留两位小数 现在导出的功能已经做出来了 但是数据里面有一些小数点后面有很多位的 导出来的表格不美观 想要实现导出表格内的数字都四舍五入保留两位小数 要怎么操作呢
  • 能够实现「导入/导出 Excel」的第三方常用类库有 Apache poi、Java Excel(JXL)和阿里巴巴开源的 Easyexcel 等。这么多类库该怎么选呢?在这里小编给大家推荐阿里巴巴开源的「Easyexcel」。 性能对比 poi 和 ...

    技术选型

    能够实现「导入/导出 Excel」的第三方常用类库有 Apache poi、Java Excel(JXL)和阿里巴巴开源的 Easyexcel 等。这么多类库该怎么选呢?在这里小编给大家推荐阿里巴巴开源的「Easyexcel」。

    • 性能对比
      poi 和 jxl 对内存的消耗很大,在处理大批量的数据时,容易造成内存溢出。比如处理一个 3M 的 Excel,poi 和 jxl 可能需要上百兆的内存,但 easyexcel 可能只需要几百或几千 KB(内存消耗对比有些夸张)。在性能这一块,Excel 完全是低于 poi 和 jxl。

    • 学习复杂度对比
      我最开始使用的是 poi。在学习它的时候,理解起来不难,就是操作的时候太特么的难了。因为 poi 需要自己处理数据,还有复杂的表格样式,就光是处理数据这一款就很头疼了。等你写好所有的代码,没有几百行,你是实现不了的。反观 easyexcel。它能自己处理数据,表格格式也简单,即使是小白也很容易上手。在学习成本远低于poi。

     

    EasyExcel

    EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。 64M内存1分钟内读取75M(46W行25列)的Excel,当然还有急速模式能更快,但是内存占用会在100M多一点

    真没想到!Java 导出 Excel 表格会变得如此简单优雅

     

    添加依赖

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>easyexcel</artifactId>
      <version>1.1.2-beat1</version>
    </dependency>

     

    基础用法

    只需要在 Controller 层返回 List 并增加 @ResponseExcel注解即可

    @Documented
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ResponseExcel {
    	String name() default "";
    	ExcelTypeEnum suffix() default ExcelTypeEnum.XLSX;
    	String password() default "";
    	String[] sheet() default {};
    	boolean inMemory() default false;
    	String template() default "";
    	String[] include() default {};
    	String[] exclude() default {};
    	Class<? extends WriteHandler>[] writeHandler() default {};
    	Class<? extends Converter>[] converter() default {};
    }

     

    • 返回单 sheet, 全部字段导出
    @ResponseExcel(name = "lengleng", sheet = "demoList")
    @GetMapping("/e1")
    public List<DemoData> e1() {
        List<DemoData> dataList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            DemoData data = new DemoData();
            data.setUsername("tr1" + i);
            data.setPassword("tr2" + i);
            dataList.add(data);
        }
        return dataList;
    }
    
    // 实体对象
    @Data
    public class DemoData {
    	private String username;
    	private String password;
    }

    真没想到!Java 导出 Excel 表格会变得如此简单优雅

     

    • 自定义字段属性
    @Data
    public class DemoData {
        @ColumnWidth(50)  // 定义宽度
    	@ExcelProperty("用户名") // 定义列名称
        @ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)
    	private String username;
    	@ExcelProperty("密码")
    	private String password;
    }

    真没想到!Java 导出 Excel 表格会变得如此简单优雅

     

    • 忽略部分字段
    @Data
    public class DemoData {
        @ColumnWidth(50)  // 定义宽度
    	@ExcelProperty("用户名") // 定义列名称
        @ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)
    	private String username;
    	@ExcelProperty("密码")
    	private String password;
    

    真没想到!Java 导出 Excel 表格会变得如此简单优雅

     

    导出多sheet

    @ResponseExcel(name = "lengleng", sheet = {"第一个sheet","第二个sheet"})
    @GetMapping("/e1")
    public List<List<DemoData>> e1() {
        List<List<DemoData>> lists = new ArrayList<>();
        lists.add(list());
        lists.add(list());
        return lists;
    }

    真没想到!Java 导出 Excel 表格会变得如此简单优雅

     

    设置导出加密码

    	@ResponseExcel(name = "lengleng", sheet = "sheetName",password = "lengleng")
    	@GetMapping("/e1")
    	public List<List<DemoData>> e1() {
    		List<List<DemoData>> lists = new ArrayList<>();
    		lists.add(list());
    		lists.add(list());
    		return lists;
    	}

    真没想到!Java 导出 Excel 表格会变得如此简单优雅

     

    进阶用法

    模板导出

    @ResponseExcel(name = "模板测试excel", sheet = "sheetName",template = "example.xlsx")
    @GetMapping("/e1")
    public List<DemoData> e1() {
        return list();
    }

     

    读取技巧

    Excel读取多页

    • 以上都是最基础的单页读写,在我们调用sheet()方法时,实际上都是默认第1页,那么如何读取多页?

     /**
     * 读多个或者全部sheet,这里注意一个sheet不能读取多次,多次读取需要重新读取文件
     * <p>
     * 1. 创建excel对应的实体对象 参照{@link DemoData}
     * <p>
     * 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
     * <p>
     * 3. 直接读即可
     */
     @Test
     public void repeatedRead() {
     String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
     // 读取全部sheet
     // 这里需要注意 DemoDataListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个DemoDataListener里面写
     EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).doReadAll();
     // 读取部分sheet
     fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
     ExcelReader excelReader = EasyExcel.read(fileName).build();
     // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
     ReadSheet readSheet1 =
     EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
     ReadSheet readSheet2 =
     EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
     // 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能
     excelReader.read(readSheet1, readSheet2);
     // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
     excelReader.finish();
     }
    • 可以看到doReadAll方法可以读取所有sheet页面

    • 若要读取单独的页面,用第二种方式readSheet(index),index为页面位置,从0开始计数

     

    自定义字段转换

    • 在读取写入的时候,我们可能会有这样的需求:比如日期格式转换,字符串添加固定前缀后缀等等,此时我们可以进行自定义编写

    @Data
    public class ConverterData {
     /**
     * 我自定义 转换器,不管数据库传过来什么 。我给他加上“自定义:”
     */
     @ExcelProperty(converter = CustomStringStringConverter.class)
     private String string;
     /**
     * 这里用string 去接日期才能格式化。我想接收年月日格式
     */
     @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
     private String date;
     /**
     * 我想接收百分比的数字
     */
     @NumberFormat("#.##%")
     private String doubleData;
    }
    • 如上面的CustomStringStringConverter类为自定义转换器,可以对字符串进行一定修改,而日期数字的格式化,它已经有提供注解了DateTimeFormat和NumberFormat

    • 转换器如下,实现Converter接口后即可使用supportExcelTypeKey这是判断单元格类型,convertToJavaData这是读取转换,convertToExcelData这是写入转换

    import com.alibaba.excel.converters.Converter;
    import com.alibaba.excel.enums.CellDataTypeEnum;
    import com.alibaba.excel.metadata.CellData;
    import com.alibaba.excel.metadata.GlobalConfiguration;
    import com.alibaba.excel.metadata.property.ExcelContentProperty;
    public class CustomStringStringConverter implements Converter<String> {
     @Override
     public Class supportJavaTypeKey() {
     return String.class;
     }
     @Override
     public CellDataTypeEnum supportExcelTypeKey() {
     return CellDataTypeEnum.STRING;
     }
     /**
     * 这里读的时候会调用
     */
     @Override
     public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
     GlobalConfiguration globalConfiguration) {
     return "自定义:" + cellData.getStringValue();
     }
     /**
     * 这里是写的时候会调用 不用管
     */
     @Override
     public CellData convertToExcelData(String value, ExcelContentProperty contentProperty,
     GlobalConfiguration globalConfiguration) {
     return new CellData(value);
     }
    }
    • 这里解析结果截取部分如下,原数据是字符串0 2020/1/1 1:01 1

    • 解析到一条数据:{"date":"2020年01月01日01时01分01秒","doubleData":"100%","string":"自定义:字符串0"}
       

    指定表头行数
    EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet()
     // 这里可以设置1,因为头就是一行。如果多行头,可以设置其他值。不传入也可以,因为默认会根据DemoData 来解析,他没有指定头,也就是默认1行
     .headRowNumber(1).doRead();

     

    读取表头数据

    • 只要在实现了AnalysisEventListener接口的监听器中,重写invokeHeadMap方法即可

     /**
     * 这里会一行行的返回头
     *
     * @param headMap
     * @param context
     */
     @Override
     public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
     LOGGER.info("解析到一条头数据:{}", JSON.toJSONString(headMap));
     }

     

     转换异常处理

    • 只要在实现了AnalysisEventListener接口的监听器中,重写onException方法即可

    @Override
     public void onException(Exception exception, AnalysisContext context) {
     LOGGER.error("解析失败,但是继续解析下一行:{}", exception.getMessage());
     if (exception instanceof ExcelDataConvertException) {
     ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception;
     LOGGER.error("第{}行,第{}列解析异常", excelDataConvertException.getRowIndex(),
     excelDataConvertException.getColumnIndex());
     }
     }

     

     读取单元格参数和类型

    • 将类属性用CellData封装起来

    @Data
    public class CellDataReadDemoData {
     private CellData<String> string;
     // 这里注意 虽然是日期 但是 类型 存储的是number 因为excel 存储的就是number
     private CellData<Date> date;
     private CellData<Double> doubleData;
     // 这里并不一定能完美的获取 有些公式是依赖性的 可能会读不到 这个问题后续会修复
     private CellData<String> formulaValue;
    }
    • 这样读取到的数据如下,会包含单元格数据类型

    解析到一条数据:{"date":{"data":1577811661000,"dataFormat":22,"dataFormatString":"m/d/yy h:mm","formula":false,"numberValue":43831.0423726852,"type":"NUMBER"},"doubleData":{"data":1.0,"formula":false,"numberValue":1,"type":"NUMBER"},"formulaValue":{"data":"字符串01","formula":true,"formulaValue":"_xlfn.CONCAT(A2,C2)","stringValue":"字符串01","type":"STRING"},"string":{"data":"字符串0","dataFormat":0,"dataFormatString":"General","formula":false,"stringValue":"字符串0","type":"STRING"}}

     

    同步返回

    • 不推荐使用,但如果特定情况一定要用,可以如下,主要为doReadSync方法,直接返回List

     /**
     * 同步的返回,不推荐使用,如果数据量大会把数据放到内存里面
     */
     @Test
     public void synchronousRead() {
     String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
     // 这里 需要指定读用哪个class去读,然后读取第一个sheet 同步读取会自动finish
     List<Object> list = EasyExcel.read(fileName).head(DemoData.class).sheet().doReadSync();
     for (Object obj : list) {
     DemoData data = (DemoData)obj;
     LOGGER.info("读取到数据:{}", JSON.toJSONString(data));
     }
     // 这里 也可以不指定class,返回一个list,然后读取第一个sheet 同步读取会自动finish
     list = EasyExcel.read(fileName).sheet().doReadSync();
     for (Object obj : list) {
     // 返回每条数据的键值对 表示所在的列 和所在列的值
     Map<Integer, String> data = (Map<Integer, String>)obj;
     LOGGER.info("读取到数据:{}", JSON.toJSONString(data));
     }
     }

     

    无对象的读

    • 顾名思义,不创建实体对象来读取Excel数据,那么我们就用Map接收,但这种对日期不友好,对于简单字段的读取可以使用

    • 其它都一样,监听器的继承中泛型参数变为Map即可

    public class NoModleDataListener extends AnalysisEventListener<Map<Integer, String>> {
     ...
    }
    • 结果截取如下

        解析到一条数据:{0:"字符串0",1:"2020-01-01 01:01:01",2:"1"}
     


    写入技巧

    排除特定字段和只写入特定字段

    • 使用excludeColumnFiledNames来排除特定字段写入,用includeColumnFiledNames表示只写入特定字段

     /**
     * 根据参数只导出指定列
     * <p>
     * 1. 创建excel对应的实体对象 参照{@link DemoData}
     * <p>
     * 2. 根据自己或者排除自己需要的列
     * <p>
     * 3. 直接写即可
     */
     @Test
     public void excludeOrIncludeWrite() {
     String fileName = TestFileUtil.getPath() + "excludeOrIncludeWrite" + System.currentTimeMillis() + ".xlsx";
     // 根据用户传入字段 假设我们要忽略 date
     Set<String> excludeColumnFiledNames = new HashSet<String>();
     excludeColumnFiledNames.add("date");
     // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
     EasyExcel.write(fileName, DemoData.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("模板")
     .doWrite(data());
     fileName = TestFileUtil.getPath() + "excludeOrIncludeWrite" + System.currentTimeMillis() + ".xlsx";
     // 根据用户传入字段 假设我们只要导出 date
     Set<String> includeColumnFiledNames = new HashSet<String>();
     includeColumnFiledNames.add("date");
     // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
     EasyExcel.write(fileName, DemoData.class).includeColumnFiledNames(includeColumnFiledNames).sheet("模板")
     .doWrite(data());
     }

     

     指定写入列

    • 写入列的顺序可以进行指定,在实体类注解上指定index,从小到大,从左到右排列

    @Data
    public class IndexData {
     @ExcelProperty(value = "字符串标题", index = 0)
     private String string;
     @ExcelProperty(value = "日期标题", index = 1)
     private Date date;
     /**
     * 这里设置3 会导致第二列空的
     */
     @ExcelProperty(value = "数字标题", index = 3)
     private Double doubleData;
    }

     

    复杂头写入

    • 如下图这种复杂头

    Excel解析工具easyexcel全面探索

     

    • 我们可以通过修改实体类注解实现

    @Data
    public class ComplexHeadData {
     @ExcelProperty({"主标题", "字符串标题"})
     private String string;
     @ExcelProperty({"主标题", "日期标题"})
     private Date date;
     @ExcelProperty({"主标题", "数字标题"})
     private Double doubleData;
    }

     

    重复多次写入

    • 分为三种:1. 重复写入同一个sheet;2. 同一个对象写入不同sheet;3. 不同的对象写入不同的sheet

    /**
     * 重复多次写入
     * <p>
     * 1. 创建excel对应的实体对象 参照{@link ComplexHeadData}
     * <p>
     * 2. 使用{@link ExcelProperty}注解指定复杂的头
     * <p>
     * 3. 直接调用二次写入即可
     */
     @Test
     public void repeatedWrite() {
     // 方法1 如果写到同一个sheet
     String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
     // 这里 需要指定写用哪个class去读
     ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
     // 这里注意 如果同一个sheet只要创建一次
     WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
     // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来
     for (int i = 0; i < 5; i++) {
     // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
     List<DemoData> data = data();
     writeSheet.setSheetName("模板");
     excelWriter.write(data, writeSheet);
     }
     /// 千万别忘记finish 会帮忙关闭流
     excelWriter.finish();
     // 方法2 如果写到不同的sheet 同一个对象
     fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
     // 这里 指定文件
     excelWriter = EasyExcel.write(fileName, DemoData.class).build();
     // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
     for (int i = 0; i < 5; i++) {
     // 每次都要创建writeSheet 这里注意必须指定sheetNo
     writeSheet = EasyExcel.writerSheet(i, "模板"+i).build();
     // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
     List<DemoData> data = data();
     excelWriter.write(data, writeSheet);
     }
     /// 千万别忘记finish 会帮忙关闭流
     excelWriter.finish();
     // 方法3 如果写到不同的sheet 不同的对象
     fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
     // 这里 指定文件
     excelWriter = EasyExcel.write(fileName).build();
     // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
     for (int i = 0; i < 5; i++) {
     // 每次都要创建writeSheet 这里注意必须指定sheetNo。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变
     writeSheet = EasyExcel.writerSheet(i, "模板"+i).head(DemoData.class).build();
     // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
     List<DemoData> data = data();
     excelWriter.write(data, writeSheet);
     }
     /// 千万别忘记finish 会帮忙关闭流
     excelWriter.finish();
     }

     

    图片导出

    • 对图片的导出,可能会有这样的需求,它提供了四种数据类型的导出,还是很丰富的

    @Test
     public void imageWrite() throws Exception {
     String fileName = TestFileUtil.getPath() + "imageWrite" + System.currentTimeMillis() + ".xlsx";
     // 如果使用流 记得关闭
     InputStream inputStream = null;
     try {
     List<ImageData> list = new ArrayList<ImageData>();
     ImageData imageData = new ImageData();
     list.add(imageData);
     String imagePath = TestFileUtil.getPath() + "converter" + File.separator + "img.jpg";
     // 放入四种类型的图片 实际使用只要选一种即可
     imageData.setByteArray(FileUtils.readFileToByteArray(new File(imagePath)));
     imageData.setFile(new File(imagePath));
     imageData.setString(imagePath);
     inputStream = FileUtils.openInputStream(new File(imagePath));
     imageData.setInputStream(inputStream);
     EasyExcel.write(fileName, ImageData.class).sheet().doWrite(list);
     } finally {
     if (inputStream != null) {
     inputStream.close();
     }
     }
     }
    • 图片类为

    @Data
    @ContentRowHeight(100)
    @ColumnWidth(100 / 8)
    public class ImageData {
     private File file;
     private InputStream inputStream;
     /**
     * 如果string类型 必须指定转换器,string默认转换成string
     */
     @ExcelProperty(converter = StringImageConverter.class)
     private String string;
     private byte[] byteArray;
    }

    导出结果:两行四列,每列都对应一张图片,四种导出类型均可

    Excel解析工具easyexcel全面探索

     

    • 其中StringImageConverter自定义转换器为

    public class StringImageConverter implements Converter<String> {
     @Override
     public Class supportJavaTypeKey() {
     return String.class;
     }
     @Override
     public CellDataTypeEnum supportExcelTypeKey() {
     return CellDataTypeEnum.IMAGE;
     }
     @Override
     public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
     GlobalConfiguration globalConfiguration) {
     throw new UnsupportedOperationException("Cannot convert images to string");
     }
     @Override
     public CellData convertToExcelData(String value, ExcelContentProperty contentProperty,
     GlobalConfiguration globalConfiguration) throws IOException {
     return new CellData(FileUtils.readFileToByteArray(new File(value)));
     }
    }

     

    字段宽高设置

    • 设置实体类注解属性即可

    @Data
    @ContentRowHeight(10)
    @HeadRowHeight(20)
    @ColumnWidth(25)
    public class WidthAndHeightData {
     @ExcelProperty("字符串标题")
     private String string;
     @ExcelProperty("日期标题")
     private Date date;
     /**
     * 宽度为50
     */
     @ColumnWidth(50)
     @ExcelProperty("数字标题")
     private Double doubleData;
    }

     

    自定义样式

    • 实现会比较复杂,需要做头策略,内容策略,字体大小等

     @Test
     public void styleWrite() {
     String fileName = TestFileUtil.getPath() + "styleWrite" + System.currentTimeMillis() + ".xlsx";
     // 头的策略
     WriteCellStyle headWriteCellStyle = new WriteCellStyle();
     // 背景设置为红色
     headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
     WriteFont headWriteFont = new WriteFont();
     headWriteFont.setFontHeightInPoints((short)20);
     headWriteCellStyle.setWriteFont(headWriteFont);
     // 内容的策略
     WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
     // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
     contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
     // 背景绿色
     contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
     WriteFont contentWriteFont = new WriteFont();
     // 字体大小
     contentWriteFont.setFontHeightInPoints((short)20);
     contentWriteCellStyle.setWriteFont(contentWriteFont);
     // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
     HorizontalCellStyleStrategy horizontalCellStyleStrategy =
     new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
     // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
     EasyExcel.write(fileName, DemoData.class).registerWriteHandler(horizontalCellStyleStrategy).sheet("模板")
     .doWrite(data());
     }
    • 效果如下

    Excel解析工具easyexcel全面探索

     

    单元格合并

     @Test
     public void mergeWrite() {
     String fileName = TestFileUtil.getPath() + "mergeWrite" + System.currentTimeMillis() + ".xlsx";
     // 每隔2行会合并。当然其他合并策略也可以自己写
     LoopMergeStrategy loopMergeStrategy = new LoopMergeStrategy(2, 0);
     // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
     EasyExcel.write(fileName, DemoData.class).registerWriteHandler(loopMergeStrategy).sheet("模板").doWrite(data());
     }
    • 效果如下,第一列单元格数据,2,3两行合并

    Excel解析工具easyexcel全面探索

     

    自动列宽

    • 根据作者描述,POI对中文的自动列宽适配不友好,easyexcel对数字也不能准确适配列宽,他提供的适配策略可以用,但不能精确适配,可以自己重写

    • 想用就注册处理器LongestMatchColumnWidthStyleStrategy

     @Test
     public void longestMatchColumnWidthWrite() {
     String fileName =
     TestFileUtil.getPath() + "longestMatchColumnWidthWrite" + System.currentTimeMillis() + ".xlsx";
     // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
     EasyExcel.write(fileName, LongestMatchColumnWidthData.class)
     .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("模板").doWrite(dataLong());
     }

     

    下拉,超链接

    • 下拉,超链接等功能需要自定义实现

     @Test
     public void customHandlerWrite() {
     String fileName = TestFileUtil.getPath() + "customHandlerWrite" + System.currentTimeMillis() + ".xlsx";
     // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
     EasyExcel.write(fileName, DemoData.class).registerWriteHandler(new CustomSheetWriteHandler())
     .registerWriteHandler(new CustomCellWriteHandler()).sheet("模板").doWrite(data());
     }
    • 其中主要为处理器CustomCellWriteHandler类,其实现CellWriteHandler接口,我们在后处理方法afterCellDispose做处理

    public class CustomCellWriteHandler implements CellWriteHandler {
     private static final Logger LOGGER = LoggerFactory.getLogger(CustomCellWriteHandler.class);
     @Override
     public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
     Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
     }
     @Override
     public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
     Head head, Integer relativeRowIndex, Boolean isHead) {
     }
     @Override
     public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
     List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
     // 这里可以对cell进行任何操作
     LOGGER.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex());
     if (isHead && cell.getColumnIndex() == 0) {
     CreationHelper createHelper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper();
     Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL);
     hyperlink.setAddress("https://github.com/alibaba/easyexcel");
     cell.setHyperlink(hyperlink);
     }
     }
    }

     

    不创建对象的写

    • 在设置write的时候不设置对象类,在head里添加List > 的对象头

    @Test
     public void noModleWrite() {
     // 写法1
     String fileName = TestFileUtil.getPath() + "noModleWrite" + System.currentTimeMillis() + ".xlsx";
     // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
     EasyExcel.write(fileName).head(head()).sheet("模板").doWrite(dataList());
     }
     
     private List<List<String>> head() {
     List<List<String>> list = new ArrayList<List<String>>();
     List<String> head0 = new ArrayList<String>();
     head0.add("字符串" + System.currentTimeMillis());
     List<String> head1 = new ArrayList<String>();
     head1.add("数字" + System.currentTimeMillis());
     List<String> head2 = new ArrayList<String>();
     head2.add("日期" + System.currentTimeMillis());
     list.add(head0);
     list.add(head1);
     list.add(head2);
     return list;
     }

     

     总结

    • 不知不觉列出了这么多easyexcel的使用技巧和方式,这里应该囊括了大部分我们工作中常用到的excel读写技巧,欢迎收藏查阅

     

    展开全文
  • 在数据的父元素上加上 style="mso-number-format:'\@';
     在数据的父元素上加上  style="mso-number-format:'\@';"
    展开全文
  • ExcelWriter实现导出Excel表格数据由文本转换为数字问题 最近在上班的时候一直在处理顾客那边数据导出Excel表格的问题,因为是大量数据拼接而来的所以在导出的时候,客户反应说导出的Excel是文本格式的不利于统计的...

    ExcelWriter实现导出Excel表格数据由文本转换为数字问题

    最近在上班的时候一直在处理顾客那边数据导出Excel表格的问题,因为是大量数据拼接而来的所以在导出的时候,客户反应说导出的Excel是文本格式的不利于统计的工作。而因为我是用的Hutool工具类ExcelWriter来实现导出Excel表的,所以常规的对单元格类型转换的方法没办法使用在网上参考了他人的文章;算是解决了这个问题。

    链接: https://blog.csdn.net/zhanxiaochu/article/details/95309634

    1.下面贴上自己封装的代码,如果头更简洁的方法欢迎大家指正

    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellType;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    /**
     * 适用于 Hutool工具类ExcelWriter导出Excel
     * sheet 里 下标从 0 开始
     * @param writer  ExcelWriter writer = ExcelUtil.getWriter();
     * @param list excel 写入的数据
     * @param rowNum  从第几行 0-第一行
     * @param columnNum 从第几列 0--第一列
     * @param columnTotalNum 总列数
     */
    public static void cellWordsToNumbers(ExcelWriter writer, List list, int rowNum, int columnNum, int columnTotalNum) {
    
        //单元格对象
        Sheet sheet = writer.getSheet();
    
        // excel 的文本格式转换为数字格式
        for (int r = rowNum; r <= list.size(); r++) {
            Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }
    
            // 列处理
            for(int c = columnNum; c <= columnTotalNum; c++){
                Cell cell = row.getCell(c);
                if(cell != null && cell.getCellType() == CellType.STRING){
                    String userViews = String.valueOf(cell.getStringCellValue());
                    // 转换为 Double 类型
                    row.getCell(c).setCellValue(Double.parseDouble(userViews));
                }
    
            }
        }
    
    }
    
    展开全文
  • 导出excel表格,可以不导入任何包,直接生产excel 如代码:html页面就一个简单的javascript脚本: window.location = "<%=request.getContextPath()%>/servlet/TestServlet";来跳转到servlet。 servlet中设置...
  • 用poi导出excel后,打开excel并且拉宽表格数字的小数点多!解决办法1.在后台把数值类型变成String类型,导出后拉宽表格不会再。但导出后的数字变成了文本类型无法直接进行计算(可转换)2.设置cellstyle的格式...
  • 在用POI导出Excel表格数字框的左上角有个绿色的小三角,看着很不舒服,如下图所示:   目的:当单元格为数字时,不要转为文本输出,就直接按数字格式输出,去掉左上角的绿色小三角形。   解决办法:在网上找...
  • layui 导出 excel 表格

    2019-04-19 13:43:00
    最近这个项目中,涉及到了导出excel表格这个功能,这个后台管理使用的是layui这个框架,大体来说还是很方便,节省了很多的开发时间。 看layui的官网社区论坛,很多人都说layui自带的导出功能,只能导出当前页面的...
  • 转 PHP导出Excel表格

    2017-03-22 13:00:51
    转自http://www.leixuesong.cn/1199 在我们PHP开发的工作中,PHP导出Excel报表和下载可能是网站系统比较常见的...Excel报表可以方便用来公司财务对账、数据的处理和统计分析。下面就讲解下PHP导出Excel表格的常用方法。
  • 在日常工作中,经常会碰到需要将数据导出excel表格中,便于打印等功能 下面就通jxl来将编辑excel表格并且导出 public String createExcel(File savePath, List<JSONObject> data) { if (data == null) {...
  • 最近因项目需要,需要开发一个模块,把系统中的一些数据导出Excel,修改后再导回系统。就趁机对这个研究了一番,下面进行一些总结。 基本上导出的文件分为两种: 1:类Excel格式,这个其实不是传统意义上的Excel...
  • php导出EXCEL表格

    2017-07-11 13:35:30
    很多时候,数据库中的数据需要导出成excel,以下是最简便的方法,不用导出excel的类,即使功能简单,但是对于没有复杂需求的项目“见效快”("Content-type:application/vnd.ms-excel"); header("Content-...
  • 一般的文件导出都是后端进行导出,最近一个项目遇到导出接口挂掉了,前端实现导出的情况。 背景是vue框架,iView组件。可以直接使用exportCsv方法进行导出。...表格点击一下就会自动变成数字的,但是对于...
  • 使用python将数据导出excel表格

    千次阅读 2020-07-26 11:54:28
    本文就介绍python导出excel表格的方法。   导出excel表格,python提供了两个库:xlwt,xlrd。本文只讨论下大致框架 import xlwt import xlrd #xlwt,xlrd是python将数据导入excel表格使用的库 wb = xlwt.Workbook()...
  • POI导出Excel表格

    2016-09-01 16:31:26
    在最近的工作中遇到了需要把数据导出Excel表格的问题,在网上找了一圈,感觉POI比较合适,POI有两个不同的分支吧,我也不知道该叫两个版本还是叫两个分支,暂且就叫分支吧,一个是org.apache.poi.hssf包下的,大...
  • 1.将html输出成excel 如果有单元格合并。  protected void btnExportHtml_Click(object sender, EventArgs e) { string path = Request.MapPath("~/Downloaded/data.html"); Response
  • JAVA导出EXCEL实现

    万次阅读 多人点赞 2019-07-31 18:39:28
    JAVA导出EXCEL实现
  • poi导出excel表格开箱即用这个是导出表格到桌面,非常不错的一个工具 类,poi的jar包就不用多说了,直接去apache的官网上下载就可以了,下面是工具类的核心代码。 import java.io.IOException; import java.io....
  • 在做项目中,遇到导出excel表格时,银行账户号数字过长,导出的数字串变为计数法形式,如下图: 网上搜到解决方法,粘贴到这以供学习。不断更新。 原博地址:...
  • PHP 导出Excel表格

    2019-05-22 16:55:23
    PHP的表格导出比较简单 设置header头。 header("Content-Disposition: inline; filename=文件名.csv");#inline 设置浏览器类型我内嵌类型 header('Content-Type: application/octet-stream');#表示文件类型为二...
  • easyexcel导出Excel表格

    千次阅读 2019-07-20 18:43:13
    easyexcel相比较poi不是一套成熟的框架,...整个excel表是一个workbook,下面有多个sheet,一个sheet有多行row,一行有多个cell 效果 第一步 引入maven依赖 <dependency> <groupId>com.alibaba<...
  • Java导出excel表格

    万次阅读 多人点赞 2013-05-31 10:40:06
    之前做项目的时候需要数据库导出excel格式,由于项目赶没完成,现在分享下如何用java导出excel。话不多说案例如下:     首先要做的是导入一个jxl的包,网上很多。首先是不连接数据库数据 package jxlTest; ...
  • 在vue中使用vue-json-excel,导出excel表格数据 表格 安装插件 npm:npm install vue-json-excel -S yarn:yarn add vue-json-excel -S 在main.js中引入 import JsonExcel from 'vue-json-excel' Vue.component('...
  • 开发中经常会涉及到数据导入、导出excel表格,所以下面介绍下操作excel的方式: 目前操作excel表格有两个框架:apache poi 和jexcelapi jxl,项目中poi用的更多所以这里介绍下poi。 首先需要在pom文件中引入poi....
  • Java POI 导出Excel表格并下载

    千次阅读 2017-04-11 14:12:13
    开发项目中,经常会用到要求导出Excel表格的情况,在网上查了很多,最后实现了功能,特此记录一下。 前台jsp页面是用ajax实现传参的 //导出数据--表格 function exportLabType(){ //选择要导出的数据 var array = ...
  • 目录 背景描述 技术准备 导出Excel——尝鲜版 导出Excel——封装版(通过反射) 导出Excel——深度封装(设置下拉选项...最近博主在做的Web项目中,有一个导出数据到Excel表格的需求,之前用纯JS实现过,这次打算...
  • java 导出excel表格1.前言2.项目环境3.maven依赖4. 代码演示3.1.创建表头3.2 绘制数据5.整体代码6. 导出到本地配置6.1nginx配置6.2前端代码 1.前言 前几周,划水划的正嗨,客户突然说要加个数据批量导出成excel表格...
  • javaScript下载excel表格 HTML <a class="btn btn-primary pull-right ml15" onclick="tableToExcel()">导出</a> <td style="width: 120px;" class="towDeci">12.0000</td> <a id=...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,367
精华内容 4,546
关键字:

导出的excel表格数字变了