实习期间遇到了一个这样的需求,业务要求将试题详情进行导出。但是看到页面展示的试题详情后,发现是使用<div>等标签遍历的数据,这就需要在服务端将数据进行处理,以下为我的实现方式:
在html页面里,可以这样请求:
var url = "请求路径/方法名?"参数A="+参数A的值+"&参数B="+e参数B的值;
window.open(url, "批量导出试卷");
服务端代码如下:
有关文件操作的依赖:
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.0.8</version>
</dependency>
controller层:
@GetMapping("/importExamPaper")
public void importExamPaper(HttpServletResponse response,
@RequestParam(value = "simPaperID") Integer simPaperID,
@RequestParam(value = "userID") String userID,
@RequestParam(value = "courseName") String courseName,
@RequestParam(value = "identityCardId") String identityCardId,
@RequestParam(value = "clickTime") Date clickTime,
@RequestParam(value = "submitTime") Date submitTime,
@RequestParam(value = "spendTime") Integer spendTime,
@RequestParam(value = "memberName") String memberName){
//做题记录详情(Comprehensive是你的实体类,记录考生信息和试卷信息)
Comprehensive comprehensive = new Comprehensive();
comprehensive.setSimPaperID(simPaperID);
comprehensive.setUserID(userID);
List<Comprehensive> list = XXXXService.getXXXDetail(comprehensive);
//利用流式操作对 List<Comprehensive> 中的对象进行遍历,并为每个对象设置一个序号,序号从 1 开始递增。这样就可以为列表中的对象添加顺序信息,以便后续处理或展示时进行参考。
AtomicInteger num = new AtomicInteger(1);
list.stream().forEach(o->{
o.setSequence(num.get());
num.getAndIncrement();
});
try {
//清空缓存
response.reset();
// 定义浏览器响应表头,并定义下载名
String fileName = URLEncoder.encode(memberName+"做题详情.doc", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename="+fileName);
//定义下载的类型,标明是word文件
response.setContentType("application/msword;charset=UTF-8");
//把创建好的word写入到输出流
byte[] bytes1 = getExamPaperWordOutputBytes(memberName,identityCardId,courseName,clickTime,submitTime,spendTime,list);
ByteArrayInputStream inStream = new ByteArrayInputStream(bytes1);
// 循环取出流中的数据
byte[] b = new byte[2048];
int len;
try (ServletOutputStream outStream = response.getOutputStream()) {
while ((len = inStream.read(b)) > 0) {
outStream.write(b, 0, len);
}
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}catch (Exception e){
e.printStackTrace();
}
}
调用方法:
/*试卷导出字节流*/
public byte[] getExamPaperWordOutputBytes(String memberName, String identityCardId, String courseName, Date clickTime, Date submitTime, Integer spendTime, List<Comprehensive> list){
byte[] outBytes=null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();//构建字节输出流
Document document = new Document(PageSize.A4); // 创建word文档,并设置纸张的大小
RtfWriter2.getInstance(document, baos);
//开始设置doc样式
document.open();
// 设置字体
BaseFont font = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);
// 主标题字体风格
Font titleFont = new Font(font, 20, Font.BOLD);
// 副标题字体风格
Font subTitleFont = new Font(font, 12, Font.BOLD);
// 正文字体风格
Font contextFont = new Font(font, 12, Font.NORMAL);
//大标题
Paragraph title = new Paragraph("试题详情");
// 设置标题格式对齐方式
title.setAlignment(Element.ALIGN_CENTER);
title.setFont(titleFont);
document.add(title);
if (org.apache.commons.lang.StringUtils.isEmpty(identityCardId)) {
identityCardId = " 暂无 ";
}
//日期格式转化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String clickTimeStr = sdf.format(clickTime);
String submitTimeStr = sdf.format(submitTime);
//用户信息
Paragraph userInfoTitle = new Paragraph("学生姓名:" + memberName + " 身份证号码:" + identityCardId + " 课程名称:" + courseName + " 开始做题时间:" + clickTimeStr + " 提交时间:" + submitTimeStr + " 做题时长:" + spendTime + "秒");
// 设置标题格式对齐方式
userInfoTitle.setAlignment(Element.ALIGN_CENTER);
userInfoTitle.setFont(subTitleFont);
document.add(userInfoTitle);
Paragraph tabTitle = new Paragraph("");
document.add(tabTitle);
// 数据输出
int i = 1;//每个题目的序号
//每个题目开始遍历
for (Comprehensive paperQuestion : list) {
Paragraph questionTitle = new Paragraph(i + ". " + paperQuestion.getContent());
// 设置标题格式对齐方式
questionTitle.setAlignment(Element.ALIGN_LEFT);
questionTitle.setFont(contextFont);
document.add(questionTitle);
List<Options> optionList = paperQuestion.getOptions();
//开始每个题目的选项进行遍历
for (Options questionOption : optionList) {
Paragraph optionTitle = new Paragraph(questionOption.getQuesValue() + ". " + questionOption.getQuesOption());
//如果是判断题只要“对”,“错“ 去掉”Y“,”N“
if ("Y".equals(questionOption.getQuesValue()) || "N".equals(questionOption.getQuesValue())) {
optionTitle = new Paragraph(questionOption.getQuesOption());
}
// 设置标题格式对齐方式
optionTitle.setAlignment(Element.ALIGN_LEFT);
if (null != paperQuestion.getUserAnswer() && questionOption.getQuesValue().equals(paperQuestion.getUserAnswer())) {
contextFont.setColor(Color.red);
}
optionTitle.setFont(contextFont);
document.add(optionTitle);
contextFont.setColor(Color.black);
}
Paragraph userAnswerTitle = new Paragraph("您的答案:" + paperQuestion.getUserAnswer());
// 设置标题格式对齐方式
userAnswerTitle.setAlignment(Element.ALIGN_LEFT);
userAnswerTitle.setFont(contextFont);
document.add(userAnswerTitle);
Paragraph answerTitle = new Paragraph("正确答案:" + paperQuestion.getAnswer());
// 设置标题格式对齐方式
answerTitle.setAlignment(Element.ALIGN_LEFT);
answerTitle.setFont(contextFont);
document.add(answerTitle);
Paragraph analysisTitle = new Paragraph("解析:" + paperQuestion.getAnalysis());
// 设置标题格式对齐方式
analysisTitle.setAlignment(Element.ALIGN_LEFT);
analysisTitle.setFont(contextFont);
document.add(analysisTitle);
i++;
document.add(new Paragraph(""));
}
document.close();
//把创建好的word写入到输出流
outBytes = baos.toByteArray();
}catch (Exception e){
e.printStackTrace();
}
return outBytes;
}
实体类这里就不展示了,基本的属性,需要注意的是选项属性是一个集合形式的:
//选项
private List<Options> options;
public class Options {
//题目ID
private String questionId;
//选项内容
private String quesOption;
//选项值
private String quesValue;
//题号
private Integer sequence;
public String getQuestionId() {
return questionId;
}
public void setQuestionId(String questionId) {
this.questionId = questionId;
}
public String getQuesOption() {
return quesOption;
}
public void setQuesOption(String quesOption) {
this.quesOption = quesOption;
}
public String getQuesValue() {
return quesValue;
}
public void setQuesValue(String quesValue) {
this.quesValue = quesValue;
}
public Integer getSequence() {
return sequence;
}
public void setSequence(Integer sequence) {
this.sequence = sequence;
}
}
这样就可以实现题目导出为Word的操作辣,如果有问题欢迎大家与我交流!
标签:Font,Word,Springboot,thymeleaf,Paragraph,new,document,public,String From: https://blog.csdn.net/m0_62458640/article/details/139779490