浏览器js调用后端java服务模块下载excel文档到本地

自由自在,废话省略

 

因为excel文档是一部分需要自动填充,另外一部分 需要手动写入,所以后端只获取存在于数据库中的数据,

1.生成文档结构(一行数据)如下:

 

 

 2.后端生成excel代码:

package com.adao.review.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
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.ss.usermodel.CellStyle;

import com.linyang.review.util.ExcelUtil;

/**
 * 
 * 生成excel文件相关逻辑
 * 
 * @author TT 2020-03-14
 */
public class FileService {
	public String createExcel(Map<String, String> dataMap) {
		System.out.println("Create excel start ... ");
		// 定义文档标题以及对应dataMap的key
		final String[] titles = { "[责任人]*", "流程状态*", "标题", "描述和建议", "所属项目", "严重性", "提出人", "派生来源", "[关联对象]", "[对象编号]",
				"评审点", "附件" };
		final String[] attrs = { "owner", "status", "flowName", "advise", "project", "ponderance", "creator", "source",
				"object", "code", "point", "accessory" };

		FileOutputStream output = null;

		String sheetName = "sheet";
		String fileName = dataMap.get("flowName")+"-评审缺陷模板";
		String fileParentpath = "D:\\Program Files\\power\\temp\\";
		File file = new File(fileParentpath + fileName + ".xls");
		
		// 创建HSSFWorkbook对象
		HSSFWorkbook wb = exportExcel(dataMap, sheetName, titles, attrs);

		try {
			if (!file.getParentFile().exists()) {
				file.getParentFile().mkdirs();
			}
			// 生成或者覆盖
			file.createNewFile();
			output = new FileOutputStream(file);
			wb.write(output);
			output.flush();
			System.out.println("Create excel :" + file.toString());
		} catch (Exception e) {
			System.out.println("error :" + e);
		} finally {
			try {
				if (output != null) {
					output.close();
				}
			} catch (IOException e) {
				System.out.println("error :" + e);
			}
		}
		return file.getName();

	}

	public static HSSFWorkbook exportExcel(Map<String, String> datas, String sheetName, String[] titles,
			String[] attrs) {
		HSSFWorkbook wb = new HSSFWorkbook(); // 创建HSSFWorkbook对象
		HSSFSheet sheet = ExcelUtil.createSheet(wb, sheetName);
		HSSFRow r; // 行
		HSSFCell c; // 列
		CellStyle headcs = wb.createCellStyle(); // 表头样式实例
		CellStyle bodycs = wb.createCellStyle(); // 内容样式实例
		bodycs.setDataFormat(wb.createDataFormat().getFormat("@")); // 设置报表内容为文本
//		System.out.println("titles.length" + titles.length);
		// 1、标题设置
		r = sheet.createRow((int) 0);
		for (int i = 0; i < titles.length; i++) {
			c = r.createCell(i);
			c.setCellValue(titles[i]);
			c.setCellStyle(ExcelUtil.createHeadCellStyle(wb, headcs));

		}
		// 2、表格内容填充以及样式设置
		r = sheet.createRow((int) 1);
		for (int j = 0; j < titles.length; j++) {
			String attr = attrs[j];
			String attrValue = getStrFromMap(attr, datas, "");
			c = r.createCell(j);
			c.setCellValue(attrValue);
			c.setCellStyle(ExcelUtil.createBodyCellStyle(bodycs));
		}
		// copy,多生成一行
		r = sheet.createRow((int) 2);
		for (int j = 0; j < titles.length; j++) {
			String attr = attrs[j];
			String attrValue = getStrFromMap(attr, datas, "");
			c = r.createCell(j);
			c.setCellValue(attrValue);
			c.setCellStyle(ExcelUtil.createBodyCellStyle(bodycs));
		}
		
		sheet.autoSizeColumn((short) 2); // 调整第三列宽度
		sheet.autoSizeColumn((short) 4); // 调整第五列宽度

		return wb;
	}
	/**
	 * 从获取数据中进行查找对应,没有的值为空
	 * @param name
	 * @param map
	 * @param defaultValue
	 * @return
	 */
	public static String getStrFromMap(String name, Map<String, String> map, String defaultValue) {
		try {
			String value = map.get(name);
			if (value == null) {
				return defaultValue;
			} else {
				return value.toString();
			}
		} catch (Exception e) {
			return defaultValue;
		}
	}

}
public class ExcelUtil {
    public static HSSFSheet createSheet(HSSFWorkbook wb, String sheetName){
		HSSFSheet sheet = wb.createSheet(sheetName);
		sheet.setDefaultColumnWidth(12);
		sheet.setGridsPrinted(false);
		//表格阴影取消 (这一条坑了我很久),不注销的话生成的excel空白处都是白板,没有阴影
//		sheet.setDisplayGridlines(false);
		return sheet;
	}

/**
	 * 创建表头CellStyle样式
	 * @param 	wb	  HSSFWorkbook对象
	 * @param   cs    cellStyle实例	
	 * @return
	 */
	public static CellStyle createHeadCellStyle(HSSFWorkbook wb, CellStyle cs){
		cs.setBorderBottom(CellStyle.BORDER_THIN); // 设置border
		cs.setBorderLeft(CellStyle.BORDER_THIN);
		cs.setBorderRight(CellStyle.BORDER_THIN);
		cs.setBorderTop(CellStyle.BORDER_THIN);
		cs.setAlignment(CellStyle.ALIGN_CENTER);  // 设置水平对齐
		Font f = wb.createFont();                 // 设置字体
		f.setBoldweight(Font.BOLDWEIGHT_BOLD);
//		f.setFontHeightInPoints((short) 11); // 大小
		cs.setFont(f);
		cs.setFillForegroundColor((short) 13);

		return cs;
	}
	
	/**
	 * 创建表格内容CellStyle样式
	 * @param cs  cellStyle实例
	 * @return
	 */
	public static CellStyle createBodyCellStyle(CellStyle cs){
		cs.setBorderBottom(CellStyle.BORDER_THIN);  // 设置border
		cs.setBorderLeft(CellStyle.BORDER_THIN);
		cs.setBorderRight(CellStyle.BORDER_THIN);
		cs.setBorderTop(CellStyle.BORDER_THIN);
		cs.setAlignment(CellStyle.ALIGN_CENTER);   // 设置水平对齐
		cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);// 设置垂直对齐
		cs.setWrapText(false);               // 设置是否自动换行
		return cs;
	}
}

  

3.前端增加按钮进行下载导出,后端返回给前端文件路径,前端获取并调用下载。可以使用三种方式

 附上添加按钮操作代码,

objectId为前端调用后端时,给后端传的关键参数

 

var rdm_url = window.location.href;
//console.info(rdm_url);

if(rdm_url.indexOf("/pages/workflow/entityTab.jsf?workflowType=REW&objectId=")>0){
//debugger;
initScript([powerPath + "scripts/workflow/entity.js"]);

//调用方法  地址栏名字是什么就传什么参数
var objectId = getObjectId(rdm_url);
var domain = getDomain(rdm_url);

//console.info('---------------------------------');
//console.info(objectId);
//console.info(domain);
//console.info('---------------------------------');

	var $list = $(".dropdown-menu-list ul");
	var h = "<li onclick='exportEntityTem();' val='Export Template' class='dropdown-menu-list-item'><a class='dropdown-

menu-list-item-link' style='padding-bottom: 6px; padding-top: 6px;'><div class='dropdown-menu-list-item-div' 

onmouseover='showCommonTip($(this))' title='导出为缺陷评审模板' style='width: 109px;'>导出为缺陷评审模板</div></a></li>";
$list.append(h);


	function exportEntityTem(){
	//debugger;
		labelCall("com.linyang.review.ReviewExport","exportToTemplate",[objectId],function(d){
			if(d){
				var url= domain + "temp/" + d ;
		//		rdmAlert("url = " +url );
				console.log("url = " +url );
				
				//下载文件
				downloadFile(url);
			}else{
				rdmAlert("download fail");
			}
		});
	}
}

function downloadFile(url){
    //定义一个form表单,通过form表单来发送请求
    var form=$("<form>");

    //设置表单状态为不显示
    form.attr("style","display:none");

    //method属性设置请求类型为post
    form.attr("method","post");

    //action属性设置请求路径,
    //请求类型是post时,路径后面跟参数的方式不可用
    //可以通过表单中的input来传递参数
    form.attr("action",url);
    $("body").append(form);//将表单放置在web中

    //在表单中添加input标签来传递参数
    //如有多个参数可添加多个input标签
    var input1=$("<input>");
    input1.attr("type","hidden");//设置为隐藏域
    //input1.attr("name","id");//设置参数名称
    //input1.attr("value","123");//设置参数值
    form.append(input1);//添加到表单中

    form.submit();//表单提交
}

//获取参数objectId
function  getObjectId(rdm_url) {
//     var query = window.location.search.substring(1);
	var vars = rdm_url.split("&");
	for (var i=0;i<vars.length;i++) {
		var pair = vars[i].split("=");
		if(pair[0] =='objectId'){
			return pair[1];
		}
  	}
  	return(false);
}

//获取服务域名
function getDomain(rdm_url){
	var var1s = rdm_url.split(":");
	var var2s = var1s[2].split("/");
	var address = var1s[0] + ":" + var1s[1];
	var port = var2s[0] ;
	var domain = address + ":" + port + "/" ;
	//console.log("domain = " + domain);
	return domain ;
}

  另外 downloadFile方法为post方法,另外提供其他几种方法

//get
//例如:url为htpp://127.0.0.1/test
function downloadFile(url){

    //定义一个form表单,通过form表单来发送请求
    var form=$("<form>");

    //设置表单状态为不显示
    form.attr("style","display:none");

    //method属性设置请求类型为get
    form.attr("method","get");

    //action属性设置请求路径,(如有需要,可直接在路径后面跟参数)
    //例如:htpp://127.0.0.1/test?id=123
    form.attr("action",url);

    //将表单放置在页面(body)中
    $("body").append(form);

    //表单提交
    form.submit();
}

//window.open 该方式许多浏览器不兼容,会出现打开新标签并关闭的效果。且txt、xml等文本文件浏览器会自动解析,
window.open("htpp://127.0.0.1/test.rar");

//download.js 改方法也是可行的,没有亲测。
具体请看官网:http://danml.com/download.html

 

 -------------------------------------------------- 更新 2020.4.18

程序运行过程中发现 如果对某一个字段需要单独处理的时候,需要做一些修改 ,将单元格的样式全部放在了方法体内。这样保证每个单元格处理相互不会影响。

public static HSSFWorkbook exportExcel(Map<String, Object> datas, String sheetName, String[] titles,
			String[] attrs) {
		HSSFWorkbook wb = new HSSFWorkbook(); // 创建HSSFWorkbook对象
		HSSFSheet sheet = ExcelUtil.createSheet(wb, sheetName);
		HSSFRow row; // 行
		HSSFCell c; // 列

		CellStyle bodycs = wb.createCellStyle(); // 内容样式实例
		bodycs.setDataFormat(wb.createDataFormat().getFormat("@")); // 设置报表内容为文本
		List<String> adviceList = new ArrayList<String>();
		adviceList = (List<String>) datas.get("adviceList");

		// 1、标题设置
		// 表头样式实例
		row = sheet.createRow((int) 0);
		for (int i = 0; i < titles.length; i++) {
			if (5 == i) {
				ExcelUtil.createHeadCellStyleRed(wb, row, i, titles[i]);
			} else {
				ExcelUtil.createHeadCellStyle(wb, row, i, titles[i]);
			}
		}
		// 需要多行内容
		String adviceKey = null;
		String adviceValue = null;
		int bodyRow = adviceList.size();
		if (0 == adviceList.size() || null == adviceList) {
			bodyRow = 1;
		}
		for (int i = 1; i < bodyRow + 1; i++) {

			int k = 1;
			if (!adviceList.isEmpty()) {
				for (String str : adviceList) {
					if (i == k) {
						String[] adviceArr = str.split("=");
						adviceKey = adviceArr[0];
						adviceValue = adviceArr[1];
					}
					k++;
				}
			}
			row = sheet.createRow((int) i);
			for (int j = 0; j < titles.length; j++) {
				String attr = attrs[j];
				String attrValue = getStrFromMap(attr, datas, "");
				if (2 == j) {
					attrValue = StringUtil.strFormatNormal(adviceValue);
					ExcelUtil.createBodyCellStyleLeft(wb, row, j, attrValue);
				}
				if (7 == j) {
					attrValue = StringUtil.strFormatNormal(adviceKey);
					ExcelUtil.createBodyCellStyle(wb, row, j, attrValue);
				} else {
					ExcelUtil.createBodyCellStyle(wb, row, j, attrValue);
				}
			}

		}
		// 设置sheet样式等
		setSheetStyle(sheet, bodyRow);

		return wb;
	}

  

/**
	 * 创建表头CellStyle样式
	 * 
	 * @param wb    HSSFWorkbook对象
	 * @param r     HSSFRow实例
	 * @param i     单元格编号
	 * @param value 单元格内容
	 *
	 */
	public static void createHeadCellStyle(HSSFWorkbook wb, HSSFRow r, int i, String value) {
		HSSFCell cell = r.createCell(i);
		// 设置字体
		Font font = wb.createFont();
		font.setBoldweight(Font.BOLDWEIGHT_BOLD);//加粗
//		font.setFontHeightInPoints((short) 11); // 大小

		// 设置style
		CellStyle style = wb.createCellStyle();
		style.setBorderBottom(CellStyle.BORDER_THIN); // 设置border
		style.setBorderLeft(CellStyle.BORDER_THIN);
		style.setBorderRight(CellStyle.BORDER_THIN);
		style.setBorderTop(CellStyle.BORDER_THIN);
		style.setAlignment(CellStyle.ALIGN_CENTER); // 设置水平对齐
		style.setFillForegroundColor((short) 13);

		style.setFont(font);
		cell.setCellStyle(style);
		cell.setCellValue(value);
	}

	/**
	 * 创建表头CellStyle样式 红色字体
	 * 
	 * @param wb    HSSFWorkbook对象
	 * @param r     HSSFRow实例
	 * @param i     单元格编号
	 * @param value 单元格内容
	 *
	 */
	public static CellStyle createHeadCellStyleRed(HSSFWorkbook wb, HSSFRow r, int i, String value) {
		HSSFCell cell = r.createCell(i);
		// 设置字体
		Font font = wb.createFont();
		font.setBoldweight(Font.BOLDWEIGHT_BOLD);
		//redFont.setFontName("宋体");
//		font.setFontHeightInPoints((short) 11); // 大小
		font.setColor(Font.COLOR_RED);//红色

		// 设置style
		CellStyle style = wb.createCellStyle();
		style.setBorderBottom(CellStyle.BORDER_THIN); // 设置border
		style.setBorderLeft(CellStyle.BORDER_THIN);
		style.setBorderRight(CellStyle.BORDER_THIN);
		style.setBorderTop(CellStyle.BORDER_THIN);
		style.setAlignment(CellStyle.ALIGN_CENTER); // 设置水平对齐
		style.setFillForegroundColor((short) 13);

		style.setFont(font);
		cell.setCellStyle(style);
		cell.setCellValue(value);
		return style;
	}

ex:

 

 

  

posted @ 2020-03-17 19:00  adao  阅读(908)  评论(0编辑  收藏  举报