java导出excel的两种方式

article/2025/8/29 23:33:17

博主简介:原互联网大厂tencent员工,网安巨头Venustech员工,阿里云开发社区专家博主,微信公众号java基础笔记优质创作者,csdn优质创作博主,创业者,知识共享者,欢迎关注,点赞,收藏。

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。”
https://www.cbedai.net/xander

在这里插入图片描述
一、在后台实现,利用java的poi
1、导入jar包,需要导入lib文件夹下如下包:
poi-3.11-20141221.jar
poi-ooxml.jar
poi-ooxml-schemas.jar
2、在util下写一个公共类,该类主要利用Jakarta POI HSSF API组件(用于操作Excel的组件),主要部分包括Excel对象,样式和格式,还有辅助操作。

 常用组件:HSSFWorkbook        excel的文档对象HSSFSheet           excel的表单HSSFRow             excel的行HSSFCell            excel的格子单元HSSFFont            excel字体HSSFDataFormat      日期格式HSSFHeader         sheet头HSSFFooter         sheet尾(只有打印的时候才能看到效果)样式:HSSFCellStyle                       cell样式辅助操作包括:HSSFDateUtil                        日期HSSFPrintSetup                      打印HSSFErrorConstants                  错误信息表

3、该类的操作代码如下:

package com.bdqn.util;import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;public class ExportExcel {// 显示的导出表的标题private String title;// 导出表的列名private String[] rowName;private List<Object[]> dataList = new ArrayList<Object[]>();// 构造函数,传入要导出的数据public ExportExcel(String title, String[] rowName, List<Object[]> dataList) {this.dataList = dataList;this.rowName = rowName;this.title = title;}// 导出数据public void export(OutputStream out) throws Exception {try {HSSFWorkbook workbook = new HSSFWorkbook();HSSFSheet sheet = workbook.createSheet(title);// 产生表格标题行HSSFRow rowm = sheet.createRow(0);HSSFCell cellTitle = rowm.createCell(0);//sheet样式定义【】HSSFCellStyle columnTopStyle=this.getColumnTopStyle(workbook);HSSFCellStyle style=this.getStyle(workbook);sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (rowName.length - 1)));cellTitle.setCellStyle(columnTopStyle);cellTitle.setCellValue(title);// 定义所需列数int columnNum = rowName.length;HSSFRow rowRowName = sheet.createRow(2);// 将列头设置到sheet的单元格中for (int n = 0; n < columnNum; n++) {HSSFCell cellRowName = rowRowName.createCell(n);cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING);HSSFRichTextString text = new HSSFRichTextString(rowName[n]);cellRowName.setCellValue(text);cellRowName.setCellStyle(columnTopStyle);}// 将查询到的数据设置到sheet对应的单元格中for (int i = 0; i < dataList.size(); i++) {Object[] obj = dataList.get(i);// 遍历每个对象HSSFRow row = sheet.createRow(i + 3);// 创建所需的行数for (int j = 0; j < obj.length; j++) {HSSFCell cell = null;if (j == 0) {cell = row.createCell(j, HSSFCell.CELL_TYPE_NUMERIC);cell.setCellValue(i + 1);} else {cell = row.createCell(j, HSSFCell.CELL_TYPE_STRING);if (!"".equals(obj[j]) && obj[j] != null) {cell.setCellValue(obj[j].toString());}}cell.setCellStyle(style);}}// 让列宽随着导出的列长自动适应for (int colNum = 0; colNum < columnNum; colNum++) {int columnWidth = sheet.getColumnWidth(colNum) / 256;for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {HSSFRow currentRow;if (sheet.getRow(rowNum) == null) {currentRow = sheet.createRow(rowNum);} else {currentRow = sheet.getRow(rowNum);}if (currentRow.getCell(colNum) != null) {HSSFCell currentCell = currentRow.getCell(colNum);if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {int length = currentCell.getStringCellValue().getBytes().length;if (columnWidth < length) {columnWidth = length;}}}}if (colNum == 0) {sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);} else {sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);}}if (workbook != null) {try {workbook.write(out);} catch (Exception e) {e.printStackTrace();}}} catch (Exception e) {}}

4、单元格样式:

/** 列头单元格样式*/public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {// 设置字体HSSFFont font = workbook.createFont();// 设置字体大小font.setFontHeightInPoints((short) 11);// 字体加粗font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 设置字体名字font.setFontName("Courier New");// 设置样式HSSFCellStyle style = workbook.createCellStyle();// 设置低边框style.setBorderBottom(HSSFCellStyle.BORDER_THIN);// 设置低边框颜色style.setBottomBorderColor(HSSFColor.BLACK.index);// 设置右边框style.setBorderRight(HSSFCellStyle.BORDER_THIN);// 设置顶边框style.setTopBorderColor(HSSFColor.BLACK.index);// 设置顶边框颜色style.setTopBorderColor(HSSFColor.BLACK.index);// 在样式中应用设置的字体style.setFont(font);// 设置自动换行style.setWrapText(false);// 设置水平对齐的样式为居中对齐;style.setAlignment(HSSFCellStyle.ALIGN_CENTER);style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);return style;}public HSSFCellStyle getStyle(HSSFWorkbook workbook) {// 设置字体HSSFFont font = workbook.createFont();// 设置字体大小font.setFontHeightInPoints((short) 10);// 字体加粗font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 设置字体名字font.setFontName("Courier New");// 设置样式;HSSFCellStyle style = workbook.createCellStyle();// 设置底边框;style.setBorderBottom(HSSFCellStyle.BORDER_THIN);// 设置底边框颜色;style.setBottomBorderColor(HSSFColor.BLACK.index);// 设置左边框;style.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 设置左边框颜色;style.setLeftBorderColor(HSSFColor.BLACK.index);// 设置右边框;style.setBorderRight(HSSFCellStyle.BORDER_THIN);// 设置右边框颜色;style.setRightBorderColor(HSSFColor.BLACK.index);// 设置顶边框;style.setBorderTop(HSSFCellStyle.BORDER_THIN);// 设置顶边框颜色;style.setTopBorderColor(HSSFColor.BLACK.index);// 在样式用应用设置的字体;style.setFont(font);// 设置自动换行;style.setWrapText(false);// 设置水平对齐的样式为居中对齐;style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 设置垂直对齐的样式为居中对齐;style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);return style;}

5、前台主要代码如下:
5.1 第一种,我们没有传入页面的查询参数,到后台我们无论怎么查询,都是把整个数据库不分条件的全部导出。不能够满足用户需求,体验不好,不推荐。

  <button type="button" class="btn btn-success" id="delPro" onclick="dao()">导出Excel</button>
function dao() {location.href="MedicineAdminServlet?a=dao&pageon="+${page.pageon};
}

5、2第二种,我们往后台传入时,把查询的参数一并传入后台,后台接收后作为条件去数据库找符合条件的,查到符合条件的导出,比较人性化。

<a href="SendMedicineServlet?a=dao&patientid=${param.patientid }&prescriptionid=${param.prescriptionid}&patientname=${param.patientname }&starttime=${param.starttime }&endtime=${param.endtime }"><button type="button" class="btn btn-success" id="delPro">导出Excel</button></a>

6、为了方便读者理解,前端页面如下:查询条件为病历号,姓名等,会根据曾经的查询条件导出。

在这里插入图片描述

7、后台servlet操作主要代码如下:(传入当前页将会只打印当前页)

/*** 导出excel文件*/else if (a.equals("dao")) {String patientid = request.getParameter("patientid");int patientid3 = 0;if (patientid != null && !patientid.equals("")) {patientid3 = Integer.parseInt(patientid);}String dname = request.getParameter("dname");String subjectroom = request.getParameter("subjectroom");String starttime = request.getParameter("starttime");String endtime = request.getParameter("endtime");// 页码int pageon = 1;String pageon1 = request.getParameter("pageon");if (pageon1 != null && !pageon1.equals("")) {pageon = Integer.parseInt(pageon1);}// 操作导出excelList<RegRum> selectlists = rs.querySelect2(patientid3, dname, subjectroom, starttime, endtime);//excel标题String title = "挂号信息表";//excel列头信息String[] rowsName = new String[] { "门诊编号", "主治医师", "挂号时间", "挂号科室", "状态" };List<Object[]> dataList = new ArrayList<Object[]>();Object[] objs = null;for (int i = 0; i < selectlists.size(); i++) {RegRum regRum = selectlists.get(i);objs = new Object[rowsName.length];objs[0] = regRum.getPatientid();objs[1] = regRum.getDoctor().getDname();SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");objs[2] = regRum.getDate();objs[3] = regRum.getDoctor().getSubroomname();objs[4] = regRum.getStatus();dataList.add(objs);}

8、下面这部分代码主要是把数据传给浏览器,前面部分告诉浏览器该数据流是什么类型的,本例传的是excel格式的,浏览器会自动判定为excel,提示是否保存。

//给文件命名。随机命名
String fileName = "Excel-" + String.valueOf(System.currentTimeMillis()).substring(4, 13) + ".xls";//告诉浏览器数据格式,将头和数据传到前台String headStr = "attachment; filename=\"" + fileName + "\"";response.setContentType("APPLICATION/OCTET-STREAM");response.setHeader("Content-Disposition", headStr);OutputStream out = response.getOutputStream();//调用poi的工具类ExportExcel ex = new ExportExcel(title, rowsName, dataList);try {ex.export(out);} catch (Exception e) {e.printStackTrace();}out.flush();out.close();return;}

9、注意:如果从数据库查到的是数字,比如0代表男,1代表女,不加处理,会导出数字,处理方法如下:(主要代码),下面代码又没有的当前页的限制,根据条件查到多少打印多少。

String patientid1 = request.getParameter("patientid");int patientid = 0;if (patientid1 != null && !patientid1.equals("")) {patientid = Integer.parseInt(patientid1);}String prescriptionid1 = request.getParameter("prescriptionid");int prescriptionid = 0;if (prescriptionid1 != null && !prescriptionid1.equals("")) {prescriptionid = Integer.parseInt(prescriptionid1);}String patientname = request.getParameter("patientname");String starttime = request.getParameter("starttime");String endtime = request.getParameter("endtime");List<Prescription> prescriptions = new ArrayList<Prescription>();prescriptions = sm.queryDao(prescriptionid, patientid, patientname, starttime, endtime);String title = "发药信息表";String[] rowsName = new String[] { "处方号", "病历号", "姓名", "日期", "状态" };List<Object[]> dataList = new ArrayList<Object[]>();//导出excelObject[] objs = null;for (int i = 0; i < prescriptions.size(); i++) {Prescription regRum = prescriptions.get(i);objs = new Object[rowsName.length];objs[0] = regRum.getPrescriptionid();objs[1] = regRum.getPatientid();objs[2] = regRum.getName();objs[3] = regRum.getPrescriptiondate();//对数字的操作if(regRum.getStatus().equals("1")) {objs[4] = "已结算";}else {objs[4]="已发药";}dataList.add(objs);}//下面代码主要跟上面一致

10.数据库操作代码如下:(比较简单,只是把满足条件的list集合传到servlet,转变为数组,方便调用poi类)

@Overridepublic List<Prescription> query(int prescriptionid,int patientid, String patientname, String starttime, String endtime, int pageon) {Connection con = Jndi.getConnection();ResultSet rs = null;PreparedStatement ps = null;String sql = "select p.patientid,p.prescriptionid,r.patientname, p.diagnose ,p.prescriptiondate,sum(chargemoney*number),p.`pstatus` \r\n"+ "from prescription p,regnum r,chargeitem c,prescriptioncharge pc  \r\n" + "\r\n"+ " where  p.patientid=r.patientid and pc.prescriptionid=p.prescriptionid\r\n" + "\r\n" + "\r\n"+ " and c.chargeid=pc.chargeid   ";if (patientid != 0) {sql = sql + " and p.patientid=" + patientid;}if (prescriptionid != 0) {sql = sql + " and p.prescriptionid=" + prescriptionid;}if (patientname != null && !patientname.equals("")) {sql = sql + " and r.patientname like '%" + patientname + "%'";}if (starttime != null && !starttime.equals("")) {sql = sql + " and p.prescriptiondate>'" + starttime + "'";}if (endtime != null && !endtime.equals("")) {sql = sql + " and p.prescriptiondate<'" + endtime + "'";}sql = sql + "  GROUP BY p.prescriptionid";
if (pageon != 0) {sql = sql + " limit " + (pageon - 1) * 4 + ",4";
}List<Prescription> listregs = new ArrayList<Prescription>();
try {ps = con.prepareStatement(sql);rs = ps.executeQuery();while (rs.next()) {Prescription prescription = new Prescription();prescription.setPatientid(rs.getInt("patientid"));prescription.setPrescriptionid(rs.getInt("p.prescriptionid"));prescription.setDiagnose(rs.getString("diagnose"));prescription.setPrescriptiondate(rs.getString("prescriptiondate"));prescription.setStatus(rs.getString("pstatus"));prescription.setSummoney(rs.getDouble(6));prescription.setName(rs.getString(3));listregs.add(prescription);}} catch (SQLException e) {e.printStackTrace();
} finally {Jndi.close(rs, ps, con);
}
return listregs;

第一种比较复杂,如果想很快搞定,可以用纯js在前端导出table表格,需要导入四个js文件。引入进去。

在这里插入图片描述
二、纯js实现前台导出excel。
1、导入js文件,可能也需要导入jquery文件,自行尝试。所需js文件地址。
链接:https://pan.baidu.com/s/14-riXUTElxWaLHRHLe04SA
提取码:fpnp

<script type="text/javascript" src="<%=path %>/Js/jszip.min.js"></script>
<script type="text/javascript" src="<%=path %>/Js/demo.page.js"></script>
<script type="text/javascript" src="<%=path %>/Js/excel-gen.js"></script>
<script type="text/javascript" src="<%=path %>/Js/FileSaver.js"></script>

2、js代码如下

<script type="text/javascript">$(document).ready(function(){alert()excel = new ExcelGen({"src_id":"test_table",//table的id"show_header":true});$("#generate-excel").click(function () {excel.generate();//执行导入包中的方法。})});
</script>

3、body中主要代码

<table class="table table-bordered table-hover definewidth m10" id="test_table">
//id在table中写
//调用方法名在button写
<button type="button" class="btn btn-success" id="generate-excel">导出Excel</button>

注意:第二种方式,只能导出当前页的信息,它是根据table里面tr的数量导的,不会打印下一页。如果希望打印下一页的内容,提供一种思路,可以在按钮上添加跳转页面,跳到另一个页面,让另一个页面返回数据库全查需要的数据,写入新建页的table中,打印新table,有兴趣的可以尝试。 到这儿,可能读累了吧,听懂的给个赞,thanks.


http://chatgpt.dhexx.cn/article/9eIj7mnB.shtml

相关文章

数据的导出方法

实现页面数据的导出 怎样实现网页数据的导出到本地&#xff0c;这里实现的是以Excel表格的格式导入到本地. 比如这样的个表格我怎样实现把数据导出放到一个到Excel表格中保存到本地&#xff0c; 从下面划红线部分可以看出这里的数据是通过三个下拉框的查询条件得到的数据&…

Pr 入门系列之十四:导出

视频工作流程中的最后一步就是导出。 Pr 中&#xff0c;可以方便地导出序列或剪辑&#xff0c;发送给他人&#xff0c;分享到社交媒体渠道&#xff0c;或者创建 DCP&#xff08;数字电影包&#xff09;文件用于影院分发。 ◆ ◆ ◆ 导出的一般流程 1、首先&#xff0c;在时间…

正态分布

正态分布 我们来对某一个年级做一项调查&#xff0c;看一看这个年级到底有多巨。于是&#xff0c;他们统计了每个同学一周刷题的时间。得到的结果如下&#xff1a; 可以看出&#xff0c;大多数人每周都有7-8个小时做题&#xff0c;有少部分蒟蒻(比如我)每周只有1-3个小时做题&…

广义pareto分布_帕累托分布广义帕累托分布

PDF、PMF、CDF 1. 概念解释 PDF:概率密度函数(probability density function), 在数学中,连续型随机变量的概率密度函数(在不至于混淆时可以简称为密度函数)是一个描述这个随机变量的输出值,在某个确定的取值点附近的可能性的函数。 PMF:概率质量函数(probability mass fun…

离散均匀分布

离散均匀分布 n 个值中的每一个具有相等的概率 1/ n 截图来源&#xff1a;Discrete Uniform Distribution 例子&#xff1a; 投掷一个骰子6个值中每个值出现的概率为 1 / 6 1/6 1/6 投掷两个骰子出现的两值之和&#xff0c;结果分布不再均匀&#xff0c;因为并非所有和的概率都…

平均分布

转载请注明出处&#xff1a;http://blog.csdn.net/liu_sn/article/details/79333368 今天遇到本很好玩的书&#xff0c;《世界是随机的:大数据时代的概率统计学》&#xff0c;在讲分布的时候作者说&#xff1a;概率分布就是概率论中的小九九。很有意思&#xff0c;看了之后确实…

边缘分布

什么是边缘分布函数&#xff0c;有那些性质 设 F ( x , y ) F(x,y) F(x,y)为随机变量 ( X , Y ) (X,Y) (X,Y)的分布函数&#xff0c;则 F ( x , y ) P { X ≤ x , Y ≤ y } F(x,y)P\{X \le x,Y \le y\} F(x,y)P{X≤x,Y≤y} 令 y → ∞ y \rightarrow \infty y→∞&#xff…

度分布的概念及形状

一、度分布的概念 把网络中节点的度按从小到大排序&#xff0c;从而统计得到度为k的节点占整个网络节点数的比例怕p k _k k​。例如下图&#xff1a; 从概率统计的角度看&#xff0c;p k _k k​也可以视为网络中一个随机选择的节点的度为k的概率&#xff0c;这就是度分布的概…

正确理解泊松分布

很多人在上概率论这门课的时候就没搞明白过泊松分布到底是怎么回事&#xff0c;至少我就是如此。虽然那个时候大家都会背“当试验的次数趋于无穷大&#xff0c;而乘积np固定时&#xff0c;二项分布收敛于泊松分布”&#xff0c;大部分的教科书上也都会给出这个收敛过程的数学推…

白话解释正态分布

复习一个统计学方面的课题&#xff0c;想找些资料看看&#xff0c;结果发现&#xff0c;就算是最基本的一些统计学概念&#xff0c;能找到的中文资料&#xff0c;读起来都是这么的佶屈聱牙&#xff0c;似乎都是从教科书里拷贝几个名词解释给放到一起&#xff0c;就算是一篇文章…

常用分布函数

0-1分布 设随机变量X只可能取0与1两个值&#xff0c;分布律为 则称X服从以p为参数的0-1分布 即 X 0 1 P 1-p p 用于描述: 对新生儿性别进行登记&#xff1b;检查产品质量是否合格&#xff1b;某车间的电力消耗是否超负荷 二项分布 设随机变量X只可能取0和1两个值&…

[R语言]正态分布

目录 分布 连续型变量的分布 正态分布 正态分布的推导 正态分布密度曲线 dnorm 正态分布的概率计算 正态分布累积曲线 总体分位数和尾概率 正态分布案例之一 R语言正态分布函数 正态分布相应的概率计算 正态分布的检验 shapiro.test()函数 Kolmogorov-Smirnov连续…

概率分布汇总

概率分布、总体分布、抽样分布&#xff0c;一开始很容易搞混&#xff0c;还以为是同一个理论&#xff0c;不同的概念&#xff0c;毕竟都是分布&#xff0c;又都是统计学里面的概率。今天就来理解理解这个东西吧。 概率分布是指随机变量的各取值与该取值对应的概率之间呈现的规…

拉普拉斯分布

如果随机变量的概率密度函数分布如下图所示&#xff0c;那么它就是拉普拉斯分布&#xff0c;记为x-Laplace&#xff08;μ,λ)&#xff0c;其中&#xff0c;μ 是位置参数&#xff0c;λ 是尺度参数。如果 μ 0&#xff0c;那么&#xff0c;正半部分恰好是尺度为 1/λ(或者λ&…

高斯分布

正态分布&#xff08;Normal distribution&#xff09;又名高斯分布&#xff08;Gaussian distribution&#xff09;&#xff0c;是一个在数学、物理及工程等领域都非常重要的概率分布&#xff0c;在统计学的许多方面有着重大的影响力。 若随机变量X服从一个数学期望为μ、标准…

机器学习小组知识点23:F分布(F Distribution)-R语言代码

F分布的用途&#xff1a;用于方差分析、协方差分析和回归分析等。 定义 一个 F -分布的随机变量是两个卡方分布变量的比率: U1/d1U2/d2=U1/U2d1/d2 其中&#xff1a; U1和U2呈卡方分布&#xff0c;它们的自由度&#xff08;degree of freedom&#xff09;分别是d1和d2。 …

F分布及其应用

F分布是1924年英国统计学家R.A.Fisher提出,并以其姓氏的第一个字母命名的。它是一种非对称分布,有两个自由度,且位置不可互换。设X服从自由度为n1的卡方分布, Y服从自由度为n2的卡方分布,且X,Y独立,则称随机变量F=(X⁄n1 )/(Y⁄n2 )服从自由度为(n1,n2)的F分布,记为F~F…

TeamTalk各个服务的IP配置方案

本人微信公众号&#xff1a;CPP进阶之旅 如果觉得这篇文章对您有帮助&#xff0c;欢迎关注 “CPP进阶之旅” 学习更多技术干货 TeamTalk各个服务的IP配置方案 1.纯公司内网2.公网ip3.公网ip&#xff0c;路由器映射相关文章重要说明 TeamTalk源码中的IM_SERVER下共有8种服务器&a…

TeamTalk部署详细教程(最全最新TeamTalk部署教程助你一次部署成功)

本人微信公众号&#xff1a;CPP进阶之旅 如果觉得这篇文章对您有帮助&#xff0c;欢迎关注 “CPP进阶之旅” 学习更多技术干货 TeamTalk部署详细教程 背景1、更新操作系统2、删除已经安装的软件3、安装必要的依赖软件4、安装mysql4.1 下载4.2 解压编译4.3 添加mysql用户4.4 修改…

新版TeamTalk部署教程

原文转自蓝狐&#xff08;bluefox&#xff09;的博客&#xff1a;https://blog.csdn.net/simongyley/article/details/45535429。对文中部分问题做了修改。 0、简介 新版TeamTalk已经在2015年03月28日发布了&#xff0c;目前版本定为1.0.0版本&#xff0c;后续版本号会按照如下…