package com.qxueyou.scc.exercise.service.impl; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.poi.POIXMLDocument; import org.apache.poi.POIXMLTextExtractor; import org.apache.poi.hwpf.extractor.WordExtractor; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.xwpf.extractor.XWPFWordExtractor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.stereotype.Service; import com.qxueyou.scc.base.model.Result; import com.qxueyou.scc.base.service.IFileUploadService; import com.qxueyou.scc.base.service.impl.CommonAppService; import com.qxueyou.scc.base.util.ClientUtils; import com.qxueyou.scc.base.util.CollectionUtils; import com.qxueyou.scc.base.util.TraceUtils; import com.qxueyou.scc.base.util.UUIDUtils; import com.qxueyou.scc.config.SccConfig; import com.qxueyou.scc.exercise.model.ExerciseGroupItemRe; import com.qxueyou.scc.exercise.model.ExerciseItem; import com.qxueyou.scc.exercise.model.ExerciseItemAnalisi; import com.qxueyou.scc.exercise.model.ExerciseItemData; import com.qxueyou.scc.exercise.model.ExerciseItemOption; import com.qxueyou.scc.exercise.model.ExerciseOptionData; import com.qxueyou.scc.exercise.service.IExercisePyService; @Service @EnableConfigurationProperties(SccConfig.class) public class ExercisePyService extends CommonAppService implements IExercisePyService { @Autowired SccConfig sccConfig; @Autowired IFileUploadService fileUploadService; private static Logger log = LogManager.getLogger("ExercisePyService"); /** * 上传解析 */ public Map parserPyExercise(String groupId, String fullPath, String module) { File file = downloadFile(groupId, fullPath, module); List lst = generateLstFromFile(file, fullPath); if (null == lst || lst.isEmpty()) { return CollectionUtils.newObjectMap("resultCode",0,"msg","文档解析内容为空"); } return exerciseParsePy(lst, fullPath); } /** * 校验 * * @param content * 习题文本内容 * @return */ public Map validatePyExercise(String content) { String[] arrLine = content.split("\n"); List lst = new ArrayList(arrLine.length); for(int i =0;i lstItems,String groupId) { if(null == lstItems || lstItems.isEmpty()){ return new Result(false, "没有记录"); } ExerciseGroupItemRe re ; ExerciseItemAnalisi analysis; ExerciseItemOption option ; ExerciseItem item ; int itemOrder = 0; String hql = "from ExerciseGroupItemRe r where r.exerciseGroupId = ? order by r.itemOrder desc "; ExerciseGroupItemRe groupRe = this.findUnique(hql, CollectionUtils.newList(groupId), ExerciseGroupItemRe.class); if( null != groupRe ){ itemOrder = groupRe.getItemOrder() ; } BigInteger iCount = BigInteger.ZERO ; try { for(ExerciseItemData data : lstItems){ item = new ExerciseItem(); re = new ExerciseGroupItemRe(); BeanUtils.copyProperties(item, data); item.setDeleteFlag(false); TraceUtils.setCreateTrace(item); this.save(item); iCount = iCount.add(BigInteger.ONE); BeanUtils.copyProperties(re, data); itemOrder++; re.setDeleteFlag(false); re.setExerciseGroupId(groupId); re.setExerciseItemId(item.getExerciseId()); re.setItemOrder(itemOrder); re.setDeleteFlag(false); this.save(re); if(StringUtils.isNotBlank(data.getAnalysis())){ analysis = new ExerciseItemAnalisi(); BeanUtils.copyProperties(analysis, data); TraceUtils.setCreateTrace(analysis); analysis.setDeleteFlag(false); analysis.setExerciseItemId(item.getExerciseId()); this.save(analysis); } if( data.getOptions() != null && !data.getOptions().isEmpty() ){ for( ExerciseOptionData opt : data.getOptions() ){ option = new ExerciseItemOption(); BeanUtils.copyProperties(option, opt); TraceUtils.setCreateTrace(option); option.setDeleteFlag(false); option.setExerciseItemId(item.getExerciseId()); this.save(option); } } } this.bulkUpdate("update ExerciseGroup set allCount = allCount + ? , " + " updateTime = sysdate(), updateId = ? , updator = ? where groupId = ? " , new Object[]{ iCount,ClientUtils.getUserId(), ClientUtils.getUserName(), groupId } ); } catch (Exception e) { log.error("解析习题copyProperties 失败:" ,e ); return new Result(false , "服务器内部转换错误"); } return new Result(true , "成功导入" + iCount + "道习题"); } private Map exerciseParsePy(List lst, String fullPath) { return pyExerciseParseByParam(lst, lst.size()); //return pyExerciseParseByCache(lst, lst.size()); } /** * post传参 * @param key * @param size * @return * @throws Exception */ private Map pyExerciseParseByParam(List lst0, int size) { return null; } /** * 缓存版本 * @param key * @param size * @return * @throws Exception */ @SuppressWarnings("unused") private Map pyExerciseParseByCache(List lst, int size){ return null; } private File downloadFile(String groupId, String fullPath, String module) { String filePart[] = fullPath.split("\\."); String fileType = filePart[filePart.length - 1]; String uuid = UUIDUtils.generateUUID(); String filePath = ExerciseService.class.getClassLoader() .getResource("../uploads").getPath() .concat("exercise/" + uuid + "/" + uuid + "." + fileType); return fileUploadService.doGetOssFile(fullPath, filePath, module, ClientUtils.getUserId()); } private List generateLstFromFile(File file, String fullPath) { String txtFilePath = transformDocToTxt(file); List lst = new ArrayList(100); FileReader reader = null; BufferedReader br = null; try { reader = new FileReader(txtFilePath); br = new BufferedReader(reader); String currLine = ""; while ((currLine = br.readLine()) != null) { if (StringUtils.isNotBlank(currLine)) { lst.add(currLine); } } } catch (Exception e) { log.error("解析练习txt文档失败:" + fullPath, e); } finally { IOUtils.closeQuietly(br); IOUtils.closeQuietly(reader); } File txt = new File(txtFilePath); FileUtils.deleteQuietly(txt); return lst; } /** * 从office转换到txt:2007转换:自带序号格式会丢失;2003会解析出来 * * @param file * @return */ private String transformDocToTxt(File file) { InputStream is = null; FileWriter writer = null; String strText = ""; try { String fileExtention = fileExtension(file.getName()); is = new FileInputStream(file.getAbsolutePath()); if ("doc".equals(fileExtention)) { WordExtractor extractor = new WordExtractor(is); // 获取Word文件中的文本+自带序号 strText = extractor.getText(); extractor.close(); } else if ("docx".equals(fileExtention)) { OPCPackage opcPackage = POIXMLDocument.openPackage(file .getAbsolutePath()); POIXMLTextExtractor extractor = new XWPFWordExtractor( opcPackage); // 只能获取Word文件中的文本,不能取到office序号 strText = extractor.getText(); extractor.close(); } else { throw new RuntimeException("文件格式错误, 请上传word文档(.doc及.docx)格式", null); } // 将得到的文本全角转半角 strText = formatFullToHalf(strText); // 解决空格保存为txt的时候,乱码为? byte bytes[] = { (byte) 0xC2, (byte) 0xA0 }; String UTFSpace = new String(bytes, "UTF-8"); strText = strText.replaceAll(UTFSpace, " "); File txtFile = new File(file.getParentFile().getAbsolutePath() + "/" + file.getName().substring(0, file.getName().lastIndexOf(".")) + ".txt"); writer = new FileWriter(txtFile, true); writer.write(strText); return txtFile.getAbsolutePath(); } catch (FileNotFoundException e) { throw new RuntimeException("office文档未找到", e); } catch (IOException e) { throw new RuntimeException("office文档读取失败", e); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } finally { IOUtils.closeQuietly(writer); IOUtils.closeQuietly(is); } } /** * 全角转半角 * * @param oriText * @return */ private String formatFullToHalf(String oriText) { if (null == oriText || oriText.length() <= 0) { return ""; } char[] charArray = oriText.toCharArray(); // 对全角字符转换的char数组遍历 for (int i = 0; i < charArray.length; ++i) { int charIntValue = (int) charArray[i]; // 如果符合转换关系,将对应下标之间减掉偏移量65248;如果是空格的话,直接做转换 if (charIntValue >= 65281 && charIntValue <= 65374) { charArray[i] = (char) (charIntValue - 65248); } else if (charIntValue == 12288) { charArray[i] = (char) 32; } else if (charIntValue == 58033) { // 空格 charArray[i] = (char) 32; } else if (charIntValue == 65380) { // 顿号 charArray[i] = (char) 12289; } else if (charIntValue == 65377) { // 句号 charArray[i] = (char) 12290; } } return new String(charArray); } /** * 解析文件后缀 * * @param filename * @return */ private String fileExtension(String filename) { return filename.substring(filename.lastIndexOf('.') + 1, filename.length()); } }