Excel 文件导出,兼容IE(web前后台导出方法)

2023-05-16

Excel 文件导出

前台导出

前台导出是指使用前台页面的数据导出到本地文件

XML文件和Excel文件之间可以相互转换,因此可将 XML 数据从 Web 服务中导入到 Excel 工作表中。

使用隐藏的Table存放需要导出的数据,构建模板文件(一个html格式文件,可以设置一些属性和格式),将table中的数据添加到模板中,通过base64加密,使用 data:application/vnd.ms-excel;base64 将数据流传送到本地,完成导出功能。

前台导出是将静态页面(包含数据的table)下载到本地

模板:

<html xmlns:o="urn:schemas-microsoft-com:office:office" 
    xmlns:x="urn:schemas-microsoft-com:office:excel"
    xmlns="http://www.w3.org/TR/REC-html40">

<head>
    <!--[if gte mso 9]>
    <xml>
        <x:ExcelWorkbook>
            <x:ExcelWorksheets>
                <x:ExcelWorksheet>
                    <x:Name>sheet页名称</x:Name>
                    <x:WorksheetOptions>
                        <x:DisplayGridlines />
                    </x:WorksheetOptions>
                </x:ExcelWorksheet>
            </x:ExcelWorksheets>
          </x:ExcelWorkbook>
    </xml>
    <![endif]-->
</head>

<body>
    <table>
       
    </table>
</body>

</html>

实现:

var worksheet = 'sheet名称'
var uri = 'data:application/vnd.ms-excel;base64,';
// 获取table元素
var strsheet = $("#table_temp").html();

// 下载的表格模板数据 
// 将table数据插入模板中
 var template = "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"";
 template += "xmlns:x=\"urn:schemas-microsoft-com:office:excel\"";
 template += "xmlns=\"http://www.w3.org/TR/REC-html40\">";
 template += "<head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>";
 template += "<x:Name>" + worksheet + "</x:Name>";
 template += "<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>";
 template += "</x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->";
 template += "</head><body><table>" + strsheet + "</table></body></html>";

//下载模板 
window.location.href = uri + base64(template);

// base64加密
function base64(str) {
      return window.btoa(unescape(encodeURIComponent(str)));
}

兼容IE

// 导出入口
function ExportExcel(tableId) {
    IeAndGoogleExcel(tableId);
}
function getExplorer() {
    var explorer = window.navigator.userAgent;

    //ie 
    //if (explorer.indexOf("MSIE") >= 0) { ---只支持IE10以下版本
    if (!!window.ActiveXObject || "ActiveXObject" in window) { //--支持IE6-IE11
        return 'ie';
    }
    //firefox 
    else if (explorer.indexOf("Firefox") >= 0) {
        return 'Firefox';
    }
    //Chrome
    else if (explorer.indexOf("Chrome") >= 0) {
        return 'Chrome';
    }
    //Opera
    else if (explorer.indexOf("Opera") >= 0) {
        return 'Opera';
    }
    //Safari
    else if (explorer.indexOf("Safari") >= 0) {
        return 'Safari';
    }
}
function IeAndGoogleExcel(tableid) {//整个表格拷贝到EXCEL中
    if (getExplorer() == 'ie') {
        AllAreaExcel(tableid);//只支持ie的导出方式
    }
    else {
        tableToExcel(tableid)//支持非ie浏览器的导出方法
    }
}

function AllAreaExcel(tableId) {

    try {
        var curTbl = document.getElementById(tableId);
        var oXL;
        oXL = new ActiveXObject("Excel.Application"); //创建AX对象excel  
        var oWB = oXL.Workbooks.Add(); //获取workbook对象  
        var oSheet = oWB.ActiveSheet;//激活当前sheet  
        var sel = document.body.createTextRange();
        sel.moveToElementText(curTbl); //把表格中的内容移到TextRange中  
        try {
            sel.select(); //全选TextRange中内容  
        } catch (e1) {
            e1.description
        }
        sel.execCommand("Copy");//复制TextRange中内容  
        oSheet.Paste();//粘贴到活动的EXCEL中  
        oXL.Visible = true; //设置excel可见属性  
        // var fname = oXL.Application.GetSaveAsFilename("fileName" + ".xls", "Excel Spreadsheets (*.xls), *.xls");
        // oWB.SaveAs(fname);
        oWB.Close();
        oXL.Quit();

    } catch (e) {
        alert(e.description);
    }
}

var tableToExcel = (function () {

    var worksheet = 'sheetName'
    var uri = 'data:application/vnd.ms-excel;base64,';
    var strsheet = $("#group_info").html();
    //下载的表格模板数据 
    var template = "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"";
    template += "xmlns:x=\"urn:schemas-microsoft-com:office:excel\"";
    template += "xmlns=\"http://www.w3.org/TR/REC-html40\">";
    template += "<head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>";
    template += "<x:Name>" + worksheet + "</x:Name>";
    template += "<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>";
    template += "</x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->";
    template += "</head><body><table>" + strsheet + "</table></body></html>";
    //下载模板 
    window.location.href = uri + base64(template);
});

后台导出

后台导出指数据在后台写入临时文件,再将文件以流的形式传递到前台。

POI

官网文档:http://poi.apache.org/components/index.html

Apache POI 是用 Java 编写的免费开源的 Java API

Apache POI 提供 API 对 Microsoft Office 格式文档读和写的功能,包括 excel、world、ppt。

思路:

调用服务获取需要导出的数据,使用 POI 提供的API 创建临时文件,并将数据写入文件中。再将文件以流的形式传递到前端。

pom 引入下面依赖:

<!--POI Office 文档的 Java 处理包-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>${pioVersion}</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>${pioVersion}</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>${pioVersion}</version>
</dependency>

创建excel文件,放入需要的数据

// 新建workbook对象
Workbook wb = new HSSFWorkbook();

// 创建 sheet页对象
Sheet sheetName = wb.createSheet("sheetName");

// 创建行对象; 从第0行开始
Row row = sheetName.createRow(0);

// cell最小单元各
Cell cell = row.createCell(0);
cell.setCellValue("0,0");

row.createCell(1).setCellValue("1,0");
row.createCell(2).setCellValue("2,0");

// 使用循环可将list数据按照自定义格式写入excel文件中

// 更多设置 比如换行、样式、字体等参考文档api

// 将数据写入输出流生成文件
try  (OutputStream fileOut = new FileOutputStream("workbook.xls")) {
    wb.write(fileOut);
}

将后台文件以流的形式反给前台

例子:可作为公共的导出接口,将临时文件写好后调用该服务返回前台

@PostMapping("/Export")
@Override
public ResponseEntity<byte[]> cdrDetailExport(@RequestParam(name = "FILE_NAME") String fileName, HttpServletResponse response) {
    // 获取配置的文件路径
    String filePath = EnvCfgUtil.getStrValue("exportfile-path");
    try{
        File cdrFile = new File(filePath+"/"+fileName);
        if(cdrFile.exists()){
            FileInputStream inputStream = null;
            try{
                inputStream = new FileInputStream(cdrFile);
                byte[] body = StreamUtils.copyToByteArray(inputStream);
                response.setContentType("application/vnd.ms-excel;charset=gbk");
                HttpHeaders headers = new HttpHeaders();
                headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
                headers.add("Content-Disposition", "attachment;filename=" +fileName);
                headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(body.length));
                ResponseEntity<byte[]> rsp = new ResponseEntity(body, headers, HttpStatus.OK);
                return rsp;
            }catch (Exception e) {
                e.printStackTrace();
                log.error("文件导出失败[{}]", e.getMessage());
                throw new BusiException("10111020000040203", "文件导出失败");
            } finally {
                if (null != inputStream) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        log.error("文件导出失败[{}]", e.getMessage());
                        throw new BusiException("10111020000040203", "文件导出失败");
                    }
                }
                cdrFile.delete();
            }
        }
    }catch(Exception e){
        e.printStackTrace();
        log.error("文件导出失败[{}]", e.getMessage());
        throw new BusiException("10111020000040203", "文件导出失败");
    }
    return null;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Excel 文件导出,兼容IE(web前后台导出方法) 的相关文章

  • 求一个数的绝对值

    java求一个数的绝对值 public static void test3 Scanner sz 61 new Scanner System in System out println 34 请输入一个数 34 int a 61 sz ne
  • Java基础Test

    判断语句 1 打印 2 求两个浮点数之商 3 对一个数四舍五入取整 4 判断一个数是否为奇数 5 求一个数的绝对值 6 求两个数的最大值 7 求三个数的最大值 import java util Scanner public class Te
  • 【libuv】入门:queue work 的跨线程异步通信

    通过阅读2012年的uv book 入门 有中文版 Handles and Requests libuv works by the user expressing interest in particular events This is
  • 九九乘法表(java)

    九九乘法表 public class Cfb public static void main String args TODO Auto generated method stub printCfb public static void p
  • Java数组应用

    1 输出三位的水仙花数 2 输出n以内的数哪些数是质数 3 打印由 组成的等腰三角形 4 打印九九乘法表 5 用1元纸币兑换1分 xff0c 2分 xff0c 5分的硬币 xff0c 要求兑换50枚 问问尅有多少种组合 xff0c 每种组合
  • java的冒泡排序

    java的冒泡排序 TODO Auto generated method stub int a 61 11 10 5 7 9 3 5 2 6 bubbleSort a 调用排序方法 show a 调用现实方法 public static v
  • Java数组选择排序

    Java数组选择排序 public static void main String args TODO Auto generated method stub int a 61 4 3 5 8 3 9 13 7 int b 61 select
  • java在有序数组内添加一个数,并按顺序排列

    java在有序数组内添加一个数 xff0c 并按顺序排列 public static void main String args TODO Auto generated method stub int a 61 1 3 5 7 9 11 1
  • 求二维数组最大值

    JaVa求二维数组最大值 public static void main String args TODO Auto generated method stub int a 61 1 2 3 4 5 6 7 8 9 int re 61 ma
  • 打印杨辉三角形JAVA数组方法

    打印杨辉三角形 public static void main String args TODO Auto generated method stub putYhTriangle 10 打印杨辉三角形 public static void
  • 九宫格随机数Java数组

    无法判断是否重复了 public class Deno7 public static void main String args 声明一个3行3列的数组 int array 61 new int 3 3 int b for int i 61
  • 开发一个表示坐标点的类Point,该类对外提供以下公有实例方法:

    开发一个表示坐标点的类Point xff0c 该类对外提供以下公有实例方法 xff1a a 设置横纵坐标 b 偏移横坐标 c 偏移纵坐标 d 偏移横纵坐标 e 求本点到另外一个点的距离 勾股定理 f 求本点到另外一个点与x轴夹角的余弦值 g
  • 开发一个人类,具有实例属性身高,体重,星座,有如下实例方法:

    import java util Random 开发一个人类 xff0c 具有实例属性身高 xff0c 体重 xff0c 星座 xff0c 有如下实例方法 xff1a a 初始化方法 xff1a 内部随机产生身高 xff08 140 200
  • 【百度智能云】基于http3的xcdn 开放直播方案设计与实践

    大神 柯老师 现有的融合CDN 0 需要集成sdk sdk 是集成在端侧 缺点 sdk 对端侧有影响 多云模式下 sdk不互通 XCDN 设计目标 保持现有cdn的优势 承载各种业务 直播点播 让各家的cdn互通 cdn 厂家屏蔽了差异性
  • 开发一个表示图书的Book类

    Book类型 public class Book 1 开发一个表示图书的Book类 该类具有私有的实例属性 xff1a 编号 名称 作者 价格 出版社 出版日期等信息 并且该类为上述属性提供公有的get和set方法 xff0c 同时该类还具
  • ATM管理者操作界面

    ATM界面 import java util Scanner public class AccountView private AccountManger am 61 new AccountManger public void regist
  • Java类的操作

    银行账户类 package com github Mrtiang public class Account 创建账户属性 private int id private double balance private double annual
  • javase类的简单应用圆与圆柱类

    圆类 package com github MrtianSuper public class Circle private double radius 61 1 设置圆的半径 无参数构造方法 public Circle this radiu
  • Java银行账户可透支类

    账户类 java package com github Mrtiang public class Account 创建账户属性 private int id private double balance private double ann
  • java继承的概念与相关应用

    继承 1 继承概述 需求说明 xff1a 设计两个类 xff1a Dog和Penguin 问题 xff1a 其中属性和方法有大量的重复 xff0c 可以优化 xff0c 使用继承 继承使用的关键字 xff1a extends xff1a 扩

随机推荐

  • Java类与继承

    继承二 1 static关键字 使用场景 xff1a 当某些场景下不需要创建多个 内容 xff0c 每个类的实例对象共享一个 内容 时就可以使用static关键字来修饰 含义 xff1a static表示静态内容 xff0c 使用stati
  • 继承,static关键字,abstract,单例模式

    1 为什么要有类的继承性 类的继承性可以减少代码冗余度 xff0c 提高代码复用性 xff0c 提高代码操作效率 2 继承的格式 xff08 语法 xff09 子类 extends 父类 3 子类继承父类后有哪些不同 子类范围大于父类 xf
  • KVM详解(一)——KVM基础知识

    今天继续给大家介绍Linux运维相关知识 xff0c 本文主要内容是KVM的基础知识 一 虚拟化简介 xff08 一 xff09 虚拟化概述 在计算机中 xff0c 虚拟化技术是一种资源管理技术 xff0c 可以将计算机的各硬件资源 xff
  • Linux桌面图形化安装详解

    今天继续给大家介绍Linux相关知识 xff0c 本文主要内容是Linux xff08 CentOS7 xff09 图形化GUI页面安装详解 一 Linux GUI图形化页面简介 尽管在运维工作中 xff0c 我们很少在Linux上安装图形
  • 【MediaSoup c#】 worker的创建

    js rust 不太熟 c 似乎还好懂一些 学习media soup 的各个组件及大体使用方式 学习其设计理念 MediasoupServer 管理worker列表 worker的表达是通过 IWorker 抽象类 拥有一个observer
  • KVM详解(三)——KVM创建虚拟机

    今天继续给大家介绍Linux运维相关知识 xff0c 本文主要内容是在KVM上创建虚拟机 一 安装准备 在前文KVM详解 xff08 二 xff09 KVM安装部署中 xff0c 我们安装了KVM 今天 xff0c 我们就来创建一个KVM的
  • KVM详解(九)——CentOS6虚拟机关机失败问题解决

    今天继续给大家介绍Linux运维相关知识 xff0c 本文主要内容是CentOS6虚拟机关机失败问题解决 一 问题描述 当我们使用KVM安装CentOS6系统后 xff0c 会发现一个问题 xff0c 即无法通过virsh shutdown
  • Python循环结构详解

    今天继续给大家介绍Python相关知识 xff0c 本文主要内容是Python循环结构 循环是一种编程语言的重要结构 xff0c 在Python中 xff0c 存在着两种循环 xff0c 一种是遍历循环 xff0c 一种是while循环 一
  • Ubuntu配置sudo命令不需要输入密码

    执行以下命令 xff1a span class token function sudo span visudo span class token comment sudo visudo默认使用的编辑器是nano xff0c 使用上下键移动
  • 智慧社区信息管理系统的设计与实现(论文打包下载)

    摘 要 近几年来 xff0c 随着网上支付方式的普及 xff0c 越来越多的人选择使用网上支付 xff0c 但由于网上支付的方式还未普及到生活的各方面 xff0c 因此本系统的完成将为物业小区提供合理的线上管理模式 xff0c 代替传统的线
  • vsftp配置详解篇

    在配置安装vsftpd过程中 xff0c 我遇到了很多坑 xff1f 查了上百篇博客 xff0c 才把这些坑一一填满 这里记录是为了方便后来者查阅 xff0c 我也是个小白 有问题请不要客气 xff0c 直接喷就是了 xff01 vsftp
  • RNN构建语言模型(用前一个单词预测下一个单词)

    训练RNN的时候 xff0c 根据反向传播 xff0c 梯度会不断相乘 xff0c 很容易出现梯度消失和梯度爆炸 通常的解决方法 xff1a 对于梯度爆炸 xff1a Gradient Clipping xff1a 如果梯度太大就把它往下卡
  • pytorch中使用tensorboard绘制Accuracy/Loss曲线(train和test显示在同一幅图中)

    因为tensorboard可以在同一幅图中显示不同文件夹下的曲线 xff0c 所以将train和test分别存到不同的文件夹里就可以在同一副图中展示 xff0c 简要记录代码 from torch utils tensorboard imp
  • Android Studio 查看当前显示的 activity

    在修复bug时 xff0c 首先需要定位到是哪个activity出现的问题 xff0c 这时可以使用adb工具 abd工具在SDK目录下的platform tools文件夹下 1 打开Android Studio的Terminal xff0
  • MyBatis:使用MyBatis Generator快速完成Springboot项目数据层开发

    使用场景 当我们使用Springboot整合Mybatis时 xff0c 我们就需要为数据库中的每一个表分别写出 xff1a 实体类Mapper xml文件Mapper接口 如果数据库中有很多表 xff0c 这个过程就会非常的繁琐 而MyB
  • 【MediaSoup】mediasoup-sfu-cpp : demo 和MediaSoup实例

    MediaSoup mediasoup sfu cpp vs2022 构建 完成了构建 下面分析其线程模型 main 进程 创建一个独立server线程支持ws 作为一个oatpp的组件存在 D span class token punct
  • “jar中没有主清单属性”问题的解决方法

    今天想要把springboot项目打成jar包部署在服务器上 xff0c 但是在使用 java jar XXX 指令时遇到了 jar中没有主清单属性 的问题 在官网上看到这样一段话 xff0c 发现是因为pom文件里没有加上repackag
  • 《Java高并发程序设计》阅读笔记

    第一章 1 同步和异步 2 并发和并行 3 临界区 xff1a 表示一种公共资源 xff0c 可以被多个线程使用 xff0c 但是每一次只能有一个线程使用它 xff0c 一旦临界区资源被占用 xff0c 其他线程想要使用这个资源就必须等待
  • Android生物认证Biometric 四十行代码轻松实现面部识别、指纹认证

    Biometric Biometric是谷歌官方提供的生物识别验证类库 xff0c 能调用包括目前Android设备上搭载的指纹 人脸 虹膜等系统级的生物认证 xff08 目前大多数的国内定制ROM可能因为安全问题 xff0c 仅支持指纹
  • Excel 文件导出,兼容IE(web前后台导出方法)

    Excel 文件导出 前台导出 前台导出是指使用前台页面的数据导出到本地文件 XML文件和Excel文件之间可以相互转换 xff0c 因此可将 XML 数据从 Web 服务中导入到 Excel 工作表中 使用隐藏的Table存放需要导出的数