Java - Execl自定义导入、导出

news2024/11/24 4:21:00
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);
}

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python-18-零基础自学python 类和子类的基础练习

学习内容&#xff1a;《python编程&#xff1a;从入门到实践》第二版 知识点&#xff1a; 类&#xff0c;父类与子类的继承&#xff0c;调用函数方法等。 练习内容&#xff1a; 练习9-7&#xff1a;管理员 管理员是一种特殊的用户。编写一个名为Admin的类&#xff0c;让它继…

linux绝对路径与相对路径区别简述

绝对路径与相对路径定义 绝对路径&#xff1a;相对于根路径&#xff0c;只要文件不移动位置&#xff0c;那么它的绝对路径是永恒不变的 相对路径&#xff1a;相对于当前所在目录而言&#xff0c;当前所在的目录可能会改变&#xff0c;所以相对路径不是固定的 路径&#xff…

算法基础入门 - 1.排序

文章目录 算法基础入门第一章:排序1.1 桶排序1.2 冒泡排序1.3 快速排序1.4 买书问题算法基础入门 第一章:排序 1.1 桶排序 该算法好比桶,假设有11个桶,编号从0-11。每出现一个数,就往对应编号的桶中放入旗子,只需要数桶中旗子的个数即可。比如2号桶有1个旗子,表示2出…

从零开始做一辆简易麦克纳姆轮小车

一、前期准备 麦克纳姆轮小车&#xff08;Mecanum wheel robot&#xff09;是一种能够实现全向移动的机器人&#xff0c;其核心在于使用了特殊设计的麦克纳姆轮。要从头开始制作一辆麦克纳姆轮小车&#xff0c;你可能需要准备以下组件和工具&#xff1a; 1. 材料和部件 麦克纳…

AIGC在游戏行业落地如何了?一起看看这篇文章

在2023年初AIGC开始被大众所认知的时候&#xff0c;游戏领域的股票一片飘红&#xff0c;AIGC被认为可以赋能游戏制作的各个环节&#xff0c;游戏板块(BK1046)从2023年初的800左右到2023年中翻倍至1600左右。 到今天&#xff0c;距离这个概念普及一年半有余&#xff0c;期待的效…

vscode安装lean4

本教程演示在Windows系统下如何安装Lean 4正式版。Linux和MacOS版本请参考Lean Manual。 如果你身在中国&#xff0c;在运行安装程序前需要做如下准备&#xff1a; 在系统目录C:\Windows\System32\drivers\etc文件夹下找到hosts文件。对于其它系统用户也都是找到各自系统的host…

Mind+在线图形编程软件(Sractch类软件)

Scratch作为图形编程软件&#xff0c;可以为小朋友学习编程提供很好的入门&#xff0c;是初次接触编程的小朋友的首选开发软件。这里介绍的Mind软件与Sractch用法几乎完全一致&#xff0c;并且可以提供在线免安装版本使用&#xff0c;浏览器直接打开网址&#xff1a; ide.mindp…

各省药品集中采购平台-地方药品集采分析数据库

国家第十批药品集中采购的启动时间暂未明确&#xff0c;但即将到来&#xff0c;在5月&#xff0c;国家医保局发布了《关于加强区域协同做好2024年医药集中采购提质扩面的通知》&#xff0c;其中明确指出将“开展新批次国家组织药品和医用耗材集中带量采购&#xff0c;对协议期满…

python爬虫--scrapy框架

Scrapy 一 介绍 Scrapy简介 1.Scrapy是用纯Python实现一个为了爬取网站数据、提取结构性数据而编写的应用框架&#xff0c;用途非常广泛2.框架的力量&#xff0c;用户只需要定制开发几个模块就可以轻松的实现一个爬虫&#xff0c;用来抓取网页内容以及各种图片&#xff0c;非…

模拟物理弧线轨道运动(模拟飞盘,子弹运动)

模拟物理弧线运动&#xff08;模拟飞盘&#xff09; 介绍实现代码总结 介绍 模拟弧线的运动&#xff0c;并且对象始终朝向运动的方向&#xff0c;模拟飞盘子弹的运动轨迹。这里我是没有加重力这么一个概念的&#xff0c;当然了重力其实比较简单可以参考我之前写的模拟抛物线运动…

2024十大首码地推拉新app平台,一手首码对接平台!

到了2024年&#xff0c;地推新应用的接单平台成为创业者们关注的焦点。对于地推行业的从业人员而言&#xff0c;选择一家拥有一手单资源的平台至关重要&#xff0c;因为这直接关系到他们的利益。 2024年如果想要进行app地推活动&#xff0c;却没有人脉渠道的困扰&#xff0c;建…

ABB机器人控制柜各模块指示灯状态说明

ABB机器人控制柜各模块指示灯状态说明 主计算机模块位于控制柜的正前方,负责机器人的各种运算处理,安全模块主要负责安全相关的信号处理,驱动单元模块用于接收上位机指令,驱动机器人运动,轴计算机模块用于接收主计算机的运动指令和串

VMware的具体使用

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 目录 一&#x1f324;️VMware的安…

直播怎么录制视频?直播视频,3种录制方法

“今晚我最喜欢的游戏博主要进行直播&#xff0c;但我可能还要加班。怎么办&#xff0c;不想错过直播的内容&#xff01;电脑怎么才能进行直播录制视频啊&#xff1f;谁能教教我&#xff1f;” 在数字化的今天&#xff0c;直播已经成为人们获取信息和娱乐的重要途径。有时&…

无线麦克风推荐哪些品牌,一文揭秘无线麦克风领夹哪个牌子好!

​究竟该如何选择麦克风呢&#xff1f;又该如何挑选无线麦克呢&#xff1f;询问我关于麦克风选择问题的人着实不少。对于那些仅仅是想要简单地自我娱乐的朋友而言&#xff0c;着实没必要去折腾&#xff0c;直接使用手机自带的麦克风便可以了。 但若是处于想要直播、拍摄短视频…

文本分类-RNN-LSTM

1.前言 本节介绍RNN和LSTM&#xff0c;并采用它们在电影评论数据集上实现文本分类&#xff0c;会涉及以下几个知识点。 1. 词表构建&#xff1a;包括数据清洗&#xff0c;词频统计&#xff0c;词频截断&#xff0c;词表构建。 2. 预训练词向量应用&#xff1a;下载并加载Glove的…

端到端图像分类算法开发实战:从 Arm 虚拟硬件到 Grove Vision AI Module V2 物理硬件

端到端图像分类算法开发实战&#xff1a;从 Arm 虚拟硬件到 Grove Vision AI Module V2 物理硬件 文章目录 1. 写在前面2. 产品简介2.1 Arm 虚拟硬件镜像产品简介2.2 Grove - Vision AI V2 产品简介 3. 实验前准备4. 实验步骤4.1 模型训练4.2 Arm 虚拟硬件镜像上的部署测试4.2…

【HarmonyOS NEXT】har 包的构建生成过程

Har模块文件结构 构建HAR 打包规则 开源HAR除了默认不需要打包的文件&#xff08;build、node_modules、oh_modules、.cxx、.previewer、.hvigor、.gitignore、.ohpmignore&#xff09;和.gitignore/.ohpmignore中配置的文件&#xff0c;cpp工程的CMakeLists.txt&#xff0c;…

【Python机器学习】自动化特征选择——迭代特征选择

在单变量测试中&#xff0c;没有使用模型&#xff1b;在基于模型的选择中&#xff0c;使用单个模型来选择特征。而在迭代特征选择中&#xff0c;将会构造一系列模型&#xff0c;每个模型都使用不同数量的特征。有两种基本方法&#xff1a; 1、开始时没有特征&#xff0c;然后逐…

【MySQL基础篇】概述及SQL指令:DDL及DML

数据库是一个按照数据结构来组织、存储和管理数据的仓库。以下是对数据库概念的详细解释&#xff1a;定义与基本概念&#xff1a; 数据库是长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。 数据库不仅仅是数据的简单堆积&#xff0c;而是遵循一定的规则…