spring boot实现自动输出word文档功能的实例代码
作者:离人散 发布时间:2021-11-10 13:37:51
标签:spring,boot,自动输出,word文档
spring boot实现自动输出word文档功能
本文用到Apache POI组件
组件依赖在pom.xml文件中添加
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
首先创建相关的实体类、编写需要用到的sql查询。
import lombok.Data;
// 选择题实体
@Data
public class MultiQuestion {
private Integer questionId;
private String subject;
private String section;
private String answerA;
private String answerB;
private String answerC;
private String answerD;
private String question;
private String level;
private String rightAnswer;
private String analysis; //题目解析
private Integer score;
}
import lombok.Data;
//填空题实体类
@Data
public class FillQuestion {
private Integer questionId;
private String subject;
private String question;
private String answer;
private Integer score;
private String level;
private String section;
private String analysis; //题目解析
}
import lombok.Data;
//判断题实体类
@Data
public class JudgeQuestion {
private Integer questionId;
private String subject;
private String question;
private String answer;
private String level;
private String section;
private Integer score;
private String analysis; //题目解析
}
创建好要用到的实体类之后,利用mybatis写sql查询,可以分为两种:1、配置mapper.xml文件路径,在xml文件中编写sql语句。2、直接使用注解。本文使用方法为第二种。
@Mapper
public interface MultiQuestionMapper {
/**
* select * from multiquestions where questionId in (
* select questionId from papermanage where questionType = 1 and paperId = 1001
* )
*/
@Select("select * from multi_question where questionId in (select questionId from paper_manage where questionType = 1 and paperId = #{paperId})")
List<MultiQuestion> findByIdAndType(Integer PaperId);
@Select("select * from multi_question")
IPage<MultiQuestion> findAll(Page page);
/**
* 查询最后一条记录的questionId
* @return MultiQuestion
*/
@Select("select questionId from multi_question order by questionId desc limit 1")
MultiQuestion findOnlyQuestionId();
@Options(useGeneratedKeys = true,keyProperty = "questionId")
@Insert("insert into multi_question(subject,question,answerA,answerB,answerC,answerD,rightAnswer,analysis,section,level) " +
"values(#{subject},#{question},#{answerA},#{answerB},#{answerC},#{answerD},#{rightAnswer},#{analysis},#{section},#{level})")
int add(MultiQuestion multiQuestion);
@Select("select questionId from multi_question where subject =#{subject} order by rand() desc limit #{pageNo}")
List<Integer> findBySubject(String subject,Integer pageNo);
}
//填空题
@Mapper
public interface FillQuestionMapper {
@Select("select * from fill_question where questionId in (select questionId from paper_manage where questionType = 2 and paperId = #{paperId})")
List<FillQuestion> findByIdAndType(Integer paperId);
@Select("select * from fill_question")
IPage<FillQuestion> findAll(Page page);
/**
* 查询最后一条questionId
* @return FillQuestion
*/
@Select("select questionId from fill_question order by questionId desc limit 1")
FillQuestion findOnlyQuestionId();
@Options(useGeneratedKeys = true,keyProperty ="questionId" )
@Insert("insert into fill_question(subject,question,answer,analysis,level,section) values " +
"(#{subject,},#{question},#{answer},#{analysis},#{level},#{section})")
int add(FillQuestion fillQuestion);
@Select("select questionId from fill_question where subject = #{subject} order by rand() desc limit #{pageNo}")
List<Integer> findBySubject(String subject,Integer pageNo);
}
//判断题
@Mapper
public interface JudgeQuestionMapper {
@Select("select * from judge_question where questionId in (select questionId from paper_manage where questionType = 3 and paperId = #{paperId})")
List<JudgeQuestion> findByIdAndType(Integer paperId);
@Select("select * from judge_question")
IPage<JudgeQuestion> findAll(Page page);
/**
* 查询最后一条记录的questionId
* @return JudgeQuestion
*/
@Select("select questionId from judge_question order by questionId desc limit 1")
JudgeQuestion findOnlyQuestionId();
@Insert("insert into judge_question(subject,question,answer,analysis,level,section) values " +
"(#{subject},#{question},#{answer},#{analysis},#{level},#{section})")
int add(JudgeQuestion judgeQuestion);
@Select("select questionId from judge_question where subject=#{subject} order by rand() desc limit #{pageNo}")
List<Integer> findBySubject(String subject,Integer pageNo);
}
写好mapper底层查询后,需要创建service及其实现类来调用mapper底层。例如:
public interface JudgeQuestionService {
List<JudgeQuestion> findByIdAndType(Integer paperId);
IPage<JudgeQuestion> findAll(Page<JudgeQuestion> page);
JudgeQuestion findOnlyQuestionId();
int add(JudgeQuestion judgeQuestion);
List<Integer> findBySubject(String subject,Integer pageNo);
}
@Service
public class JudgeQuestionServiceImpl implements JudgeQuestionService {
@Autowired
private JudgeQuestionMapper judgeQuestionMapper;
@Override
public List<JudgeQuestion> findByIdAndType(Integer paperId) {
return judgeQuestionMapper.findByIdAndType(paperId);
}
@Override
public IPage<JudgeQuestion> findAll(Page<JudgeQuestion> page) {
return judgeQuestionMapper.findAll(page);
}
@Override
public JudgeQuestion findOnlyQuestionId() {
return judgeQuestionMapper.findOnlyQuestionId();
}
@Override
public int add(JudgeQuestion judgeQuestion) {
return judgeQuestionMapper.add(judgeQuestion);
}
@Override
public List<Integer> findBySubject(String subject, Integer pageNo) {
return judgeQuestionMapper.findBySubject(subject,pageNo);
}
}
最后将输出文件方法写在controller层:
@RequestMapping("/exam/exportWord")
public void exportWord(int examCode, HttpServletResponse response) throws FileNotFoundException{
//由于题目应于考试信息对应 所以需要先查出考试信息后根据pageId来查找对应的组卷信息
ExamManage res = examManageService.findById(examCode);
int paperId = res.getPaperId();
List<MultiQuestion> multiQuestionRes = multiQuestionService.findByIdAndType(paperId); //选择题题库 1
List<FillQuestion> fillQuestionsRes = fillQuestionService.findByIdAndType(paperId); //填空题题库 2
List<JudgeQuestion> judgeQuestionRes = judgeQuestionService.findByIdAndType(paperId);
//响应到客户端
XWPFDocument document= new XWPFDocument();
//分页
XWPFParagraph firstParagraph = document.createParagraph();
//格式化段落
firstParagraph.getStyleID();
XWPFRun run = firstParagraph.createRun();
int i = 1;
run.setText("一、选择题" + "\r\n"); //换行
for (MultiQuestion multiQuestion : multiQuestionRes) {
String str = multiQuestion.getQuestion();
String str1 = multiQuestion.getAnswerA();
String str2 = multiQuestion.getAnswerB();
String str3 = multiQuestion.getAnswerC();
String str4 = multiQuestion.getAnswerD();
run.setText(i + ". " + str + "\r\n");
run.setText("A. " + str1 + "\r\n");
run.setText("B. " + str2 + "\r\n");
run.setText("C. " + str3 + "\r\n");
run.setText("D. " + str4 + "\r\n");
i++;
}
run.setText("二、填空题" + "\r\n");
for (FillQuestion fillQuestion : fillQuestionsRes) {
String str = fillQuestion.getQuestion();
run.setText(i + ". " + str + "\r\n");
i++;
}
run.setText("三、判断题" + "\r\n");
for (JudgeQuestion judgeQuestion : judgeQuestionRes) {
String str = judgeQuestion.getQuestion();
run.setText(i + ". " + str + "\r\n");
i++;
}
document.createTOC();
try {
//设置相应头
this.setResponseHeader(response, res.getSource() + "试卷.doc");
//输出流
OutputStream os = response.getOutputStream();
document.write(os);
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发送响应流方法
*/
private void setResponseHeader(HttpServletResponse response, String fileName) {
try {
try {
fileName = URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
//遵守缓存规定
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
} catch (Exception ex) {
ex.printStackTrace();
}
}
效果:
来源:https://blog.csdn.net/qq_42793254/article/details/115859007


猜你喜欢
- 目录写在前面引入guava依赖包怎么做变量转换写在前面有时候需要处理对象属性的getter、setter方法,或者将属性与数据表字段进行相互
- Hadoop环境搭建详见此文章https://www.jb51.net/article/33649.htm。我们已经知道Hadoop能够通过
- 本文实例讲述了java设计模式之工厂模式。分享给大家供大家参考,具体如下:工厂模式(factory)涉及到4个角色:抽象工厂类角色,具体工厂
- 栅栏类似闭锁,但是它们是有区别的.1.闭锁用来等待事件,而栅栏用于等待其他线程.什么意思呢?就是说闭锁用来等待的事件就是countDown事
- 本文实例讲述了C#画图之饼图折线图的实现方法,是C#程序设计中非常实用的技巧。分享给大家供大家参考。具体方法分析如下:显示图像的控件定义如下
- OKhttp3中的cookiesOkHttpClient client = new OkHttpClient().newBuilder().
- 前言在我们日常的开发中,很多时候,定时任务都不是写死的,而是写到数据库中,从而实现定时任务的动态配置,下面就通过一个简单的示例,来实现这个功
- C# 5.0 给我们带来了三个非常有用的编译器特性CallerMemberNameCallerFilePathCallerLineNumbe
- 这篇文章主要介绍了Spring boot @RequestBody数据传递过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有
- 分类1.简单工厂模式2.工厂方法模式3.抽象工厂模式案例需求根据蛋糕的不同口味,分别创建苹果味和香蕉味的蛋糕实例方案一:简单工厂模式定义蛋糕
- Android中的线程池ThreadPoolExecutor解决了单线程下载数据的效率慢和线程阻塞的的问题,它的应用也是优化实现的方式。所以
- Unity3D游戏引擎介绍Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三
- 堆排序介绍:堆排序可以分为两个阶段。在堆的构造阶段,我们将原始数组重新组织安排进一个堆中;然后在下沉排序阶段,我们从堆中按顺序取出所有元素并
- 本文实例讲述了Android程序启动时出现黑屏问题的解决方法。分享给大家供大家参考,具体如下:关于黑屏:默认的情况下,程序启动时,会有一个黑
- ListView,就如其名,是用来显示列表的一种View,而RecycleView,是其的加强版,今天带来的是这两个几乎具有相同的功能的对比
- 某些情况下,我们需要在项目中对多种任务分配不同的线程池进行执行。从而通过监控不同的线程池来控制不同的任务。为了达到这个目的,需要在项目中配置
- 在使用面向对象的语言进行项目开发的过程中,较多的会使用到“继承”的特性,但是并非所有的场景都适合使用“
- 在Android开发中;Activity之间传递参数是常见的事;如果我们要在Activity之间传递图片;1。MainActivity中包括
- 首先,类只能使用public修饰是一个伪命题,应该说我们只见到过使用public修饰的类,还有一些类没有访问修饰符,此时访问权限为defau
- 一、前言java是一门跨硬件平台的面向对象高级编程语言,java程序运行在java虚拟机上(JVM),由JVM管理内存,这点是和C++最大区