Java 获取远程excel内容-修改excel内容
需求背景
现在需要通过Java获取远程对象存储OSS的excel文件内容,并修改excel内容中的指定列的值后返回新的excel给用户下载。
前台页面
前台页面列表以及搜索条件相关的就不说了,这里直接步入主题,直接讲述对应按钮的功能,页面如图
我们需要讲的就是红色框中的按钮【导出(脱敏)】,对应按钮的html代码
html
{
title: '操作',
align: 'center',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-info btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="searchClueDaily(\'' + options.searchUrl + '\',\'' + row.accountTime + '\', \''+ row.clueType+'\')"><i class="fa fa-list"></i> 查看详情</a> ');
if(row.errorDetailUrl == null || row.errorDetailUrl == ''){
actions.push('<a class="btn btn-warning btn-xs' + clueExport + '" href="javascript:void(0)" onclick="notUrlTips()"><i class="fa fa-download"></i> 导出</a> ');
}else{
actions.push('<a class="btn btn-warning btn-xs ' + clueExport + '" href="' + row.errorDetailUrl + '"><i class="fa fa-download"></i> 导出</a> ');
actions.push('<a class="btn btn-warning btn-xs ' + clueExport + '" href="javascript:void(0)" onclick="exportData(\'' + row.errorDetailUrl + '\')"><i class="fa fa-download"></i> 导出(脱敏)</a> ');
}
return actions.join('');
}
}
对应的js代码
javascript
//errorurl为远程文件路径
function exportData(errorurl) {
window.location.href=prefix+"/exportData?url="+errorurl;
}
其中:prefix为页面全局变量,对应controller请求路径
var prefix = ctx + "project/accountClueDetail";
errorurl对应的是数据库中查出数据的远程excel文件路径,例如这样的
String errorurl= "http://yuancheng.test.com/online_crm/export/file/2021/10/20/线索获取明细_20210926_购书未购课中级_1634677384547.xlsx";
后端逻辑实现
整体实现逻辑就是先通过http请求获取远程excel的文件流,然后读取文件流内容到Workbook,再对Workbook中对应列的值进行修改,修改完成后重新创建该列并写回到表格中,最后返回表格给前端下载。
java
/**
* 导出线索统计明细列表
*/
@RequiresPermissions("project:accountClueDetail:export")
@RequestMapping("/exportData")
@ResponseBody
public void exportData(String url, HttpServletResponse response)
{
URL urlfile = null;
HttpURLConnection httpUrl = null;
OutputStream out = null;
try {
//创建url请求对象
urlfile = new URL(url);
httpUrl = (HttpURLConnection) urlfile.openConnection();
httpUrl.connect();
//创建Workbook 接收HttpURLConnection返回的输入流
Workbook workbook = WorkbookFactory.create(httpUrl.getInputStream());
//获取表格的第一个sheet
Sheet sheetAt = workbook.getSheetAt(0);
//获取sheet的行数
int rows = sheetAt.getPhysicalNumberOfRows();
for (int i = 1; i < rows; i++) {
//第0行为表头,故从第1行开始获取行数据
Row row = sheetAt.getRow(i);
//获取第3列的数据,列的计算从0来时
Cell cell = row.getCell(3);
//获取对应表格的值
String cellValue = cell.getStringCellValue();
if (StringUtils.isNotEmpty(cellValue)) {
//脱敏处理
String str = desensitizeStr(cellValue);
//重新创建第1行第3列表格数据并设置脱敏后的数据
Cell cell1 = row.createCell(3);
cell1.setCellValue(str);
}
}
response.setCharacterEncoding("UTF-8");
response.setHeader("content-type", "application/octet-stream; charset=utf-8");
//设置文件名
String dname="";
String exportName = url.substring(url.lastIndexOf("/")+1,url.lastIndexOf("."))+"(脱敏)";
try {
//针对IE或IE为内核的浏览器
if(userAgent.contains("MSIE")||userAgent.contains("Trident")) {
dname=java.net.URLEncoder.encode(exportName,"UTF-8");
}else {
//谷歌控制版本
dname=new String(exportName.getBytes("UTF-8"),"ISO-8859-1");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//设置response响应头
response.setHeader("Content-Disposition", "attachment;filename="+dname+"(脱敏).xlsx");
out = response.getOutputStream();
workbook.write(out);
//System.out.println("数据导出成功");
httpUrl.disconnect();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(out != null){
out.flush();
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 字符串 手机号 脱敏
* public static final Pattern TEXT_CONRAIN_PHONE = Pattern.compile("^(.*)(1[0-9]{9})(.*)$");
* @param sensitizeStr 脱敏字符串
* @return
*/
private String desensitizeStr(String sensitizeStr){
Matcher matcher = Regex.TEXT_CONRAIN_PHONE.matcher(sensitizeStr);
if( matcher.matches() ){
String phone = matcher.group(2);
String replaceStr = phone.substring(0, 3) + "****" + phone.substring(7);
return phone.replace(phone, replaceStr);
}
return sensitizeStr;
}
到这里就完成了,最后处理后的数据