Java - Execl自定义导入、导出

1.需求:问卷星答 下图框出区域,为用户自定义字段问题及答案

在这里插入图片描述

2.采用技术EasyExcel

模板所在位置如下
在这里插入图片描述

/**
 * 导出模板
 *
 * @param response
 */
@Override
public void exportTemplate(HttpServletResponse response) throws IOException {

	ClassPathResource classPathResource = new ClassPathResource("templates/会员满意度调研.xlsx");
	StreamUtils.copy(classPathResource.getInputStream(),response.getOutputStream());
}
3.监听Listener继承AnalysisEventListener
导入模板数据时,所用的监听器
package com.huatek.frame.modules.survey.service.impl;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Map;

@Slf4j
public class SurveyImportMessageListener extends AnalysisEventListener<Object> {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private ArrayList<Object> datas = new ArrayList();
    /**
     * 表头
     */
    private Map<Integer, String> headMap;
    public SurveyImportMessageListener() {
    }

public void invoke(Object data, AnalysisContext analysisContext) {
    this.datas.add(data);
}


public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
    this.headMap = headMap;
}

public void doAfterAllAnalysed(AnalysisContext context) {
}

public ArrayList<Object> getDatas() {
    return this.datas;
}
public Map<Integer, String> getHead() {
    return this.headMap;
}
}
4.导入问卷
/**
 * 导入问卷
 *
 * @param file
 * @param localUser
 * @return
 */
@Override
public List<String> importSurvey(MultipartFile file, String surveyMainId,UserAuthProfileInfo localUser) {
	List<String> errorList = new ArrayList<>();
	try {
		SurveyImportMessageListener listener = new SurveyImportMessageListener();
		EasyExcel.read(file.getInputStream(), listener).sheet().doRead();
		ArrayList datas = listener.getDatas();
		Map<Integer, String> head = listener.getHead();
		LinkedList<SurveyProblemAnswerVO> surveyProblemAnswerVOS = new LinkedList();
		LinkedList<SurveyProblemAnswerItemVO> surveyProblemAnswerItemVOS = new LinkedList();
		head.forEach((key,value)->{
			//存储问题
			if(key >= 6){
				SurveyProblemAnswerItemVO item = new SurveyProblemAnswerItemVO();
				item.setProblem(value);
				item.setSortBy(key);
				surveyProblemAnswerItemVOS.add(item);
			}
		});
		for (Object data : datas) {
			SurveyProblemAnswerVO survey = new SurveyProblemAnswerVO();
			List<SurveyProblemAnswerItemVO> items = BeanListUtils.copyListProperties(surveyProblemAnswerItemVOS, SurveyProblemAnswerItemVO::new);
			survey.setSurveyMainId(surveyMainId);
			((LinkedHashMap<Integer, String>) data).forEach((key,value)->{
				if(key == 1) survey.setSubmitTime(DateUtil.parse(value,"yyyy/MM/dd HH:mm:ss"));
				if(key == 2) survey.setUseTime(value);
				if(key == 3) survey.setSource(value);
				if(key == 4) survey.setSourceInfo(value);
				if(key == 5) survey.setSourceIp(value);
				//存储问题答案
				if(key >= 6){
					SurveyProblemAnswerItemVO item = items.get(key-6);
					item.setAnswer(value);
				}
			});
			survey.setItemVOList(items);
			surveyProblemAnswerVOS.add(survey);
		}
		log.info("导入问答信息:{}", JSONArray.toJSONString(surveyProblemAnswerVOS));
		for (SurveyProblemAnswerVO surveyProblemAnswerVO : surveyProblemAnswerVOS) {
			SurveyMain surveyMain = surveyMainMapper.selectById(surveyMainId);
			if(surveyMain.getImportTime() == null){
				surveyMain.setImportTime(new Date());
				HttpServletRequest request = RequestHolder.getHttpServletRequest();
				JSONObject jsonObject = securityUser.currentUser(securityUser.getToken(request));
				surveyMain.setImportBy(jsonObject.get("userName").toString());
				surveyMainMapper.updateById(surveyMain);
			}

			SurveyProblemAnswer surveyProblemAnswer = new SurveyProblemAnswer();
			BeanUtils.copyProperties(surveyProblemAnswerVO,surveyProblemAnswer);
			surveyProblemAnswerService.saveOrUpdate(surveyProblemAnswer);

			List<SurveyProblemAnswerItemVO> itemVOList = surveyProblemAnswerVO.getItemVOList();
			itemVOList.forEach(item->item.setSurveyId(surveyProblemAnswer.getId()));
			List<SurveyProblemAnswerItem> surveyProblemAnswerItems = BeanListUtils.copyListProperties(itemVOList, SurveyProblemAnswerItem::new);
			surveyProblemAnswerItemService.saveOrUpdateBatch(surveyProblemAnswerItems);
		}

	} catch(Exception e){
		log.error("导入问卷异常",e);
	}
	return errorList;
}
5.根据模板导出数据
@Override
public void exportExcel(SurveyProblemAnswerVO vo, HttpServletResponse response) throws IOException {
	List<SurveyProblemAnswer> surveyProblemAnswers = surveyProblemAnswerMapper.selectList(
			new LambdaQueryWrapper<SurveyProblemAnswer>()
			.eq(SurveyProblemAnswer::getSurveyMainId, vo.getId()));

	List<String> surveyIds = surveyProblemAnswers.stream().map(item -> item.getId()).collect(Collectors.toList());
	List<SurveyProblemAnswerItem> surveyProblemAnswerItems = surveyProblemAnswerItemMapper.selectList(
			new LambdaQueryWrapper<SurveyProblemAnswerItem>()
					.in(SurveyProblemAnswerItem::getSurveyId, surveyIds));

	LinkedList<List<String>> head = new LinkedList<>();
	head.add(CollectionUtil.newArrayList("序号"));
	head.add(CollectionUtil.newArrayList( "提交答卷时间"));
	head.add(CollectionUtil.newArrayList( "所用时间"));
	head.add(CollectionUtil.newArrayList( "来源"));
	head.add(CollectionUtil.newArrayList( "来源详情"));
	head.add(CollectionUtil.newArrayList( "来源IP"));
	List<SurveyProblemAnswerItem>  problemItems = surveyProblemAnswerItems.stream()
			.filter(item -> item.getSurveyId().equals(surveyProblemAnswers.get(0).getId()))
			.sorted(Comparator.comparing(SurveyProblemAnswerItem::getSortBy))
			.collect(Collectors.toList());
	for (SurveyProblemAnswerItem item : problemItems) {
		head.add(CollectionUtil.newArrayList( item.getProblem()));
	}


	LinkedList<List<Object>> data = new LinkedList<>();
	int count = 0;
	for (SurveyProblemAnswer surveyProblemAnswer : surveyProblemAnswers) {
		List<Object> tmp = new ArrayList<>();
		tmp.add(++count);
		tmp.add(surveyProblemAnswer.getSubmitTime() == null ? "" : surveyProblemAnswer.getSubmitTime());
		tmp.add(surveyProblemAnswer.getUseTime() == null ? "":surveyProblemAnswer.getUseTime());
		tmp.add(surveyProblemAnswer.getSource() == null ? "":surveyProblemAnswer.getSource());
		tmp.add(surveyProblemAnswer.getSourceInfo() == null ? "":surveyProblemAnswer.getSourceInfo());
		tmp.add(surveyProblemAnswer.getSourceIp() == null ? "":surveyProblemAnswer.getSourceIp());
		List<SurveyProblemAnswerItem> items = surveyProblemAnswerItems.stream()
				.filter(item -> item.getSurveyId().equals(surveyProblemAnswer.getId()))
				.sorted(Comparator.comparing(SurveyProblemAnswerItem::getSortBy))
				.collect(Collectors.toList());
		for (SurveyProblemAnswerItem item : items) {
			if(StringUtils.isNotEmpty(item.getAnswer())){
				tmp.add(item.getAnswer());
			}else{
				tmp.add("");
			}
		}
		data.add(tmp);
	}
	EasyExcel.write(response.getOutputStream(),null)
			.head(head)
			.autoCloseStream(false)
			.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("会员满意度调研模板")
			.doWrite(data);
}

以上均为实现类,具体接口可参照定义

结果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/750410.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uni-app移动端使用uni-file-picker上传图片时通过canvas添加拍摄时间等水印信息

实现效果&#xff1a; 添加的照片添加水印信息 实现方式&#xff1a; 将添加水印的方法抽离成组件&#xff0c;为Vue文件&#xff0c;方便复用&#xff0c;在父组件中直接引用即可实现水印效果。 子组件&#xff1a;waterMarker.vue 此为添加水印的组件文件&#xff0c;…

python-(opencv)视频转glf

文章目录 前言python-(opencv)视频转glf1. 下载 opencv-python2. cv2&#xff08;OpenCV&#xff09;和imageio的区别3. demo源码 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说…

YashanDB为新质生产力赋能 灌注合肥区域转型源动力

当前&#xff0c;数据要素已成为我国数字经济的“核心引擎”与“关键生产要素”&#xff0c;为全面激发数据要素的价值&#xff0c;各地区正积极探索数据要素交易平台的可行模式&#xff0c;加快在数据要素领域的布局。近日&#xff0c;深圳计算科学研究院崖山数据库系列产品受…

win10系统打开Windows更新是空白的如何解决?

最近装wsl的时候&#xff0c;遇到了这个问题。查阅了很多相关资料&#xff0c;发现导致wsl --install安装不了的主要原因都集中在于windows更新组件损坏导致的&#xff0c;经过排查&#xff0c;我的这个组件确实不能够正常使用&#xff0c;可能是因为之前使用了windows激活工具…

【Java Web】PostMan业务接口测试工具

目录 一、PostMan概述 二、如何安装Postman 三、Postman的基本使用 一、PostMan概述 在生产环境中&#xff0c;一个项目在开发之前、前后端开发工程师通常需要商讨在前后端数据交互时需要采用什么样的规范格式&#xff0c;如&#xff1a;前端向后端发送请求的uri、请求和响…

vue2.0项目安装依赖 sass 报错

1、报错代码&#xff1a; 2、原因&#xff1a;项目有点老&#xff0c;vue2的版本&#xff0c;所以node-sass在npm安装的时候大概率的会安装出错&#xff0c;或下载时间过长&#xff0c;因此考虑用dart-sass来替换。 npm install node-sassnpm:dart-sass3、然后就可以成功运行了…

【PTA】7-1 网红点打卡攻略(C/C++)代码实现 反思

解题细节分析&#xff1a; 0.比较图的两种存储方法&#xff0c;通过邻接矩阵存储更便于查找给定两点之间的关系 1.注意理解清楚题义&#xff1a;“访问所有网红点”中所有不是指攻略中所有&#xff0c;而是存在的全部的网红点 代码见下&#xff1a;// 需要注明的是&#xff…

音频剪辑技巧:音频降噪在线怎么降噪?分享7种录音去除杂音方法

相信很多小伙伴们都有这种苦恼&#xff1a;在编辑音频时&#xff0c;你可能发现即使你使用了价格昂贵的隔音麦克风&#xff0c;在录音中仍然存在呼吸声和咳嗽声。因此&#xff0c;如果要传达清晰干净的声音以表达你的信息&#xff0c;你该如何从录音去除杂音呢&#xff1f;别心…

理清时间复杂度和空间复杂度

目录 复习时间 幂函数 指数函数 对数函数 ​编辑 时间复杂度 推导阶的原则 常见的时间复杂度举例 常数阶 O(1) 对数阶 O(logn) 平方阶 O(n^2) 图像表示 空间复杂度 常见的空间复杂度举例 常数阶 O(1) 线性阶 O(n) 平方阶 O(n^2) 一个算法的优劣主要从算法的执行时间和所需要占…

elementUI的衍生组件,avue的crud表格错位问题

问题描述&#xff1a; 每次从别的页面跳转回来就发现表格显示错位了 一通查 结果发现是有两层表格 解决办法&#xff1a; 根据开发者工具中看到的样式选择器&#xff0c;很粗暴的在全局样式文件中加一个&#xff1a; 效果&#xff1a;

CDP问卷的常见问题

CDP问卷的常见问题可以归纳如下&#xff1a; 哪些企业会收到CDP邀请&#xff1f; 企业会收到来自投资和/或采购机构的邀请&#xff0c;以填写CDP问卷并披露相应的环境管理信息。 未收到邀请的企业可否填报&#xff1f; 未收到邀请的企业可以选择自行填报。他们需发送申请自愿…

[论文阅读笔记33] Matching Anything by Segmenting Anything (CVPR2024 highlight)

这篇文章借助SAM模型强大的泛化性&#xff0c;在任意域上进行任意的多目标跟踪&#xff0c;而无需任何额外的标注。 其核心思想就是在训练的过程中&#xff0c;利用strong augmentation对一张图片进行变换&#xff0c;然后用SAM分割出其中的对象&#xff0c;因此可以找到一组图…

Session会话与请求域的区别

session会话和请求域&#xff08;也称为request域&#xff09;都是用于存储和管理用户特定信息的重要概念&#xff0c;但它们在作用范围和生命周期上有显著的不同。 请求域 (Request Domain) 作用范围&#xff1a;请求域是面向单次请求的。每次HTTP请求都会创建一个新的request…

【实战教程】如何使用JMeter来轻松测试WebSocket接口?

1、websocket接口原理 打开网页&#xff1a;从http协议&#xff0c;升级到websocket协议&#xff0c;请求建立websocket连接服务器返回建立成功成功客户端向服务端发送匹配请求服务端选择一个客服上线服务器返回客服id客户端向服务器发送消息服务器推送消息给指定的客服服务器…

EXCEL快速填充空白内容

** EXCEL快速填充空白内容 ** 1.全选所有需要填充的内容&#xff0c;按住电脑的F5或者CTRLG点击定位 2.可以看到空白处被自动选定&#xff0c;之后按电脑和⬆&#xff0c;最后CTRLenter 可以看到空白处已经被填充。

C#——this关键字详情

this关键字 在 C# 中&#xff0c;可以使用 this 关键字来表示当前对象&#xff0c;日常开发中我们可以使用 this 关键字来访问类中的成员属性以及函数。 使用this表示当前类的对象 执行结果 使用 this 关键字串联构造函数 执行结果 使用 this 关键字作为类的索引器 执行结果 …

02逻辑代数与硬件描述语言基础

2.1 逻辑代数&#xff08;简单逻辑的运算&#xff09; 2.2 逻辑函数的卡诺图&#xff08;从图论的角度&#xff09;化简法 2.3 硬件描述语言Verilog HDL基础&#xff08;研究生阶段才用得到&#xff09; 要求&#xff1a; 1、熟悉逻辑代数常用基本定律、恒等式和规则。 2、掌握…

蒸汽架空管道中的关键守护者:滑动管托、导向管托与固定管托

蒸汽架空管道中的关键守护者&#xff1a;滑动管托、导向管托、固定管托与补偿器的重要角色在蒸汽架空管道系统中&#xff0c;每一个组件都扮演着不可或缺的角色&#xff0c;共同确保管道的安全、高效运行。今天&#xff0c;我们就来深入探讨滑动管托、导向管托、固定管托以及补…

用一个实例看如何分享大量照片 续篇二,关于Exif (Exchangeable Image File) - 可交换图像文件

续篇二&#xff1a;说说关于照片隐含的 Exif (Exchangeable Image File) 可交换图像文件 数码照片的Exif 参数有很多&#xff0c;重要的Exif信息&#xff1a;拍摄日期、时间、拍摄器材、GPS信息。 当然这主要对自己的档案有意义&#xff0c;如果放到网上还是建议抹去这些信息。…

50etf期权合约一手多少钱你知道吗?

今天带你了解50etf期权合约一手多少钱你知道吗&#xff1f;50etf期权有不同价值的合约&#xff0c;每手50etf期权合约从几元到几百元再到上千元的都有&#xff0c;具体需要根据投资者选择了什么价值的合约。 50etf期权权利金 50ETF期权合约的权利金是买方需要缴纳的费用&…