java使用apache.poi導出word文件的示例代碼
更新時間:2023年07月31日 09:10:11 作者:javacoffeenet
這篇文章主要介紹了java使用apache.poi導出word文件,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
功能說明:
將試卷導出word,并可以打印,裝訂,效果圖:
內部使用
下面是實現(xiàn)代碼:
package com.xxxxx.business.course.utils; import com.alibaba.fastjson.JSONObject; import com.deepoove.poi.xwpf.NiceXWPFDocument; import com.xxxxx.business.course.domain.*; import com.xxxxx.business.utils.UtilTools; import com.xxxxx.business.utils.domain.JudgeRule; import com.xxxxx.business.utils.impl.BaseImpl; import com.xxxxx.common.core.domain.R; import com.xxxxx.common.core.utils.DateUtils; import com.xxxxx.common.core.utils.StringUtils; import com.xxxxx.common.core.utils.file.FileTypeUtils; import com.xxxxx.common.core.utils.file.ImageUtils; import com.xxxxx.common.core.utils.reflect.ReflectUtils; import com.xxxxx.common.core.utils.sign.Base64; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.util.IOUtils; import org.apache.poi.util.Units; import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; import org.apache.poi.xwpf.usermodel.*; import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute; import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline; import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.*; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.util.List; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr; /** * 試卷歸檔幫助類 */ public class VerifyPaperFileUtils extends BaseImpl { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); public static VerifyPaperFileUtils getInstance() { return new VerifyPaperFileUtils(); } private VerifyPaperFileUtils() { } private Integer pageNum = 0; private XWPFDocument docx; private CTSectPr ctSectPr; private QuestionImportRule importRule = QuestionImportRule.getDefaultRule(""); private VerifyPaper verifyPaper; private PaperTemplate paperTemplate; private boolean includeAnswer = false; private String imgRegex = "img"; private String[] quSortNoArr = new String[]{"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十"}; private String rgb_black = "000000"; /** * 外部調用方法,導出word * * @param response * @param verifyPaper * @throws IOException */ public R<?> exportWord(HttpServletResponse response, VerifyPaper verifyPaper, PaperTemplate paperTemplate) throws Exception { this.verifyPaper = verifyPaper; if (paperTemplate == null) paperTemplate = VerifyPaperFileUtils.getDefaultPaperTemplate(); this.paperTemplate = paperTemplate; R<?> r = this.init(); if (!r.isSuccess()) throw new Exception(r.getMsg()); response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); response.setCharacterEncoding("utf-8"); return this.exportWord(response); } /** * 驗證相關數(shù)據(jù) * * @return */ private R<?> init() { if (this.verifyPaper == null) { return R.fail("未選擇試卷"); } if (this.verifyPaper.getVerifyPaperQtList() == null || verifyPaper.getVerifyPaperQtList().size() == 0) { return R.fail("未設置課程題型"); } if (this.verifyPaper.getVerifyPaperQtList().stream().filter(s -> s.getVerifyPaperQuList() == null || s.getVerifyPaperQuList().size() == 0).count() > 0) return R.fail("有題型未設置試題"); return validTemplate(); } private R<?> validTemplate() { if (this.paperTemplate == null) { return R.fail("未設置模板"); } return R.ok(); } /** * 導出word,私有方法 * * @param response * @throws IOException */ private R<?> exportWord(HttpServletResponse response) throws IOException, InvalidFormatException { try { R<?> r = writeWord(); if (!r.isSuccess()) return r; docx.write(response.getOutputStream()); return R.ok(); } catch (Exception e) { logger.error("導出Word異常,{}", e.getMessage()); throw e; } finally { IOUtils.closeQuietly(docx); } } /** * 試題數(shù)據(jù)寫入文檔 */ private R<?> writeWord() throws IOException, InvalidFormatException { R<XWPFDocument> r = createDocxTemplate(); if (!r.isSuccess()) return R.fail(r.getMsg()); docx = r.getData(); writePaperInfo(); writeWordQts(); return R.ok(); } /** * 制作模板 * 模板各種設置 * * @return */ private R<XWPFDocument> createDocxTemplate() { XWPFDocument document = new NiceXWPFDocument(); R<?> r = writeWordPageSetting(document); if (!r.isSuccess()) return R.fail(r.getMsg()); //整體設置 writeWordPageSetting(document); //頁眉 writeWordHeader(document); //頁腳 writeWordFooter(document); return R.ok(document); } /** * 頁面設置 * * @return */ private R<?> writeWordPageSetting(XWPFDocument docx) { if (StringUtils.isEmpty(paperTemplate.getPtPageSize())) return R.fail("未設置模板尺寸"); ctSectPr = docx.getDocument().getBody().getSectPr(); if (ctSectPr == null) ctSectPr = docx.getDocument().getBody().addNewSectPr(); CTPageSz ctPageSz = ctSectPr.isSetPgSz() ? ctSectPr.getPgSz() : ctSectPr.addNewPgSz(); switch (paperTemplate.getPtPageSize().toUpperCase()) { case "A3": ctPageSz.setW(getTwipFromCM(29.7)); //設置寬度(這里是一個ulong類型,單位:緹 , 1厘米=567緹) ctPageSz.setH(getTwipFromCM(42)); //設置高度(這里是一個ulong類型) break; case "A4": ctPageSz.setW(getTwipFromCM(21)); ctPageSz.setH(getTwipFromCM(29.7)); break; case "A5": ctPageSz.setW(getTwipFromCM(14.8)); ctPageSz.setH(getTwipFromCM(21)); break; case "B4": ctPageSz.setW(getTwipFromCM(25.7)); ctPageSz.setH(getTwipFromCM(36)); break; case "B5": ctPageSz.setW(getTwipFromCM(18.2)); ctPageSz.setH(getTwipFromCM(25.7)); break; case "16開": ctPageSz.setW(getTwipFromCM(18.4)); ctPageSz.setH(getTwipFromCM(26)); break; case "32開": ctPageSz.setW(getTwipFromCM(13)); ctPageSz.setH(getTwipFromCM(18.4)); break; case "大32開": ctPageSz.setW(getTwipFromCM(14)); ctPageSz.setH(getTwipFromCM(20.3)); break; default: return R.fail(StringUtils.format("不支持的尺寸:{}", paperTemplate.getPtPageSize())); } if (paperTemplate.getPtDirection().intValue() == 1) // 橫向 { BigInteger tempW = ctPageSz.getW(); ctPageSz.setW(ctPageSz.getH()); ctPageSz.setH(tempW); ctPageSz.setOrient(STPageOrientation.LANDSCAPE); } //設置邊距 CTPageMar pageMar = ctSectPr.getPgMar(); if (pageMar == null) pageMar = ctSectPr.addNewPgMar(); pageMar.setBottom(getTwipFromCM(paperTemplate.getPtMarginBottom().doubleValue())); pageMar.setTop(getTwipFromCM(paperTemplate.getPtMarginTop().doubleValue())); pageMar.setRight(getTwipFromCM(paperTemplate.getPtMarginRight().doubleValue())); pageMar.setLeft(getTwipFromCM(paperTemplate.getPtMarginLeft().doubleValue())); pageMar.setHeader(getTwipFromCM(paperTemplate.getPtHeaderMargin().doubleValue()));//頁眉到頂端的距離 pageMar.setFooter(getTwipFromCM(paperTemplate.getPtFooterMargin().doubleValue()));//頁腳到低端的距離 if (paperTemplate.getPtMarginBottom().doubleValue() > 2) { pageMar.setFooter(getTwipFromCM(1)); } else { double leftH = paperTemplate.getPtMarginBottom().doubleValue() - 1; if (leftH > 0) { pageMar.setFooter(getTwipFromCM(leftH)); } } //處理分欄 if (paperTemplate.getPtColumNum().intValue() > 1) { if (!ctSectPr.isSetCols()) ctSectPr.addNewCols(); if (!UtilTools.compareBigIntegerValue(BigInteger.valueOf(paperTemplate.getPtColumNum()), ctSectPr.getCols().getNum())) { CTColumns ctColumns = ctSectPr.getCols(); ctColumns.setNum(BigInteger.valueOf(paperTemplate.getPtColumNum().longValue())); ctSectPr.setCols(ctColumns); } } return R.ok(); } /** * 設置頭部 */ private void writeWordHeader(XWPFDocument docx) { if (StringUtils.isEmpty(paperTemplate.getPtSealLineType())) { paperTemplate.setPtSealLineType("once"); } XWPFHeader header = null; //STHdrFtr.Enum headerType = StringUtils.equalsIgnoreCase(paperTemplate.getPtSealLineType(), "once") ? STHdrFtr.DEFAULT : STHdrFtr.Enum.forString(paperTemplate.getPtSealLineType()); if (!StringUtils.equalsIgnoreCase(paperTemplate.getPtSealLineType(), "once")) { XWPFHeaderFooterPolicy headerFooterPolicy = docx.getHeaderFooterPolicy(); if (headerFooterPolicy == null) headerFooterPolicy = docx.createHeaderFooterPolicy(); String sealType = ""; sealType = paperTemplate.getPtSealLineType().toLowerCase(); switch (sealType) { case "default": //每頁 header = headerFooterPolicy.createHeader(STHdrFtr.DEFAULT); break; case "odd": //奇數(shù)頁 header = headerFooterPolicy.createHeader(STHdrFtr.DEFAULT); docx.setEvenAndOddHeadings(true); break; case "even": //偶數(shù)頁 header = headerFooterPolicy.createHeader(STHdrFtr.EVEN); docx.setEvenAndOddHeadings(true); break; } } if (paperTemplate.getPtPageHeadShow() && StringUtils.isNotEmpty(paperTemplate.getPtPageHeadText())) { if (header == null) { XWPFHeaderFooterPolicy headerFooterPolicy = docx.getHeaderFooterPolicy(); if (headerFooterPolicy == null) headerFooterPolicy = docx.createHeaderFooterPolicy(); header = headerFooterPolicy.createHeader(STHdrFtr.DEFAULT); } XWPFParagraph p = header.createParagraph(); if (StringUtils.isNotEmpty(paperTemplate.getPtPageHeadAlign())) p.setAlignment(Enum.valueOf(ParagraphAlignment.class, paperTemplate.getPtPageHeadAlign())); XWPFRun run = p.createRun(); run.setText(paperTemplate.getPtPageHeadText()); run.setFontSize(paperTemplate.getPtPageHeadSize()); } //在頁眉里面添加裝訂線 //制作左邊裝訂線 writeWordBroadside(docx, header); } /** * 設置側邊欄 * 換新頁面設置一個 */ private void writeWordBroadside(XWPFDocument docx, XWPFHeader header) { if (paperTemplate.getPtSealLineShow() == null || !paperTemplate.getPtSealLineShow()) return; ctSectPr = docx.getDocument().getBody().getSectPr(); if (ctSectPr == null) ctSectPr = docx.getDocument().getBody().addNewSectPr(); //創(chuàng)建一個 CTPageMar pageMar = ctSectPr.isSetPgMar() ? ctSectPr.getPgMar() : ctSectPr.addNewPgMar(); //裝訂線寬度 BigInteger slideBarWidth = pageMar.getLeft(); if (pageMar.getGutter() != null) slideBarWidth.add(pageMar.getGutter()); if (paperTemplate.getPtSealLineWidth().doubleValue() > 2.5) { slideBarWidth = slideBarWidth.subtract(getTwipFromCM(0.5)); } BigInteger cellWidth = slideBarWidth.divide(BigInteger.valueOf(2)); //BigInteger top = BigInteger.valueOf(1); BigInteger slideBarHeight = ctSectPr.getPgSz().getH().subtract(BigInteger.valueOf(2)); // 創(chuàng)建一個側邊欄 XWPFTable sidebarTable = StringUtils.equalsIgnoreCase(paperTemplate.getPtSealLineType(), "once") ? docx.createTable(1, 2) : header.createTable(1, 2); CTTblPr ctTblPr = sidebarTable.getCTTbl().getTblPr(); if (ctTblPr == null) ctTblPr = sidebarTable.getCTTbl().addNewTblPr(); //設置寬度 ctTblPr.getTblW().setType(STTblWidth.DXA); ctTblPr.getTblW().setW(slideBarWidth); // BigInteger x = BigInteger.ZERO.subtract(slideBarWidth); //居左 CTJc jcTable = ctTblPr.isSetJc() ? ctTblPr.getJc() : ctTblPr.addNewJc(); jcTable.setVal(STJc.LEFT); sidebarTable.setTableAlignment(TableRowAlign.LEFT); //定位 CTTblPPr ctTblPPr = ctTblPr.isSetTblpPr() ? ctTblPr.getTblpPr() : ctTblPr.addNewTblpPr(); ctTblPPr.setVertAnchor(STVAnchor.PAGE); ctTblPPr.setHorzAnchor(STHAnchor.PAGE); ctTblPPr.setTblpXSpec(STXAlign.LEFT); ctTblPPr.setTblpYSpec(STYAlign.TOP); ctTblPPr.setTblpX(BigInteger.ZERO); ctTblPPr.setTblpY(BigInteger.ZERO); //去除邊框 setTableBorder(sidebarTable, false); for (XWPFTableRow row : sidebarTable.getRows()) { row.setHeight(slideBarHeight.intValue()); for (XWPFTableCell cell : row.getTableCells()) { cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); CTTcPr ctTcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr(); if (!ctTcPr.isSetTcW()) ctTcPr.addNewTcW(); ctTcPr.getTcW().setW(cellWidth); //文字方向 CTTextDirection cellDirection = ctTcPr.isSetTextDirection() ? ctTcPr.getTextDirection() : ctTcPr.addNewTextDirection(); cellDirection.setVal(STTextDirection.BT_LR); //垂直居中 CTVerticalJc ctVerticalJc = ctTcPr.isSetVAlign() ? ctTcPr.getVAlign() : ctTcPr.addNewVAlign(); ctVerticalJc.setVal(STVerticalJc.Enum.forString("center")); //左對齊 CTOnOff noWap = ctTcPr.isSetNoWrap() ? ctTcPr.getNoWrap() : ctTcPr.addNewNoWrap(); noWap.setVal(STOnOff.Enum.forString("on")); } } //學生信息 XWPFTableCell cellInfo = sidebarTable.getRow(0).getCell(0); //String blankStr = " "; String blankStr = "_____________"; XWPFParagraph paragraph = cellInfo.getParagraphs().get(0); paragraph.setVerticalAlignment(TextAlignment.CENTER); paragraph.setAlignment(ParagraphAlignment.CENTER); //paragraph.setFontAlignment(2); if (paperTemplate.getPtSealLineStudentCode()) { addTextToSidebar(paragraph, " 學號:", false); addTextToSidebar(paragraph, blankStr, false); } if (paperTemplate.getPtSealLineStudentName()) { addTextToSidebar(paragraph, " 姓名:", false); addTextToSidebar(paragraph, blankStr, false); } if (paperTemplate.getPtSealLineStudentCollege()) { addTextToSidebar(paragraph, " 學院:", false); addTextToSidebar(paragraph, blankStr, false); } if (paperTemplate.getPtSealLineStudentGrade()) { addTextToSidebar(paragraph, " 年級:", false); addTextToSidebar(paragraph, blankStr, false); } if (paperTemplate.getPtSealLineStudentDepartment()) { addTextToSidebar(paragraph, " 系:", false); addTextToSidebar(paragraph, blankStr, false); } if (paperTemplate.getPtSealLineStudentSpecialty()) { addTextToSidebar(paragraph, " 專業(yè):", false); addTextToSidebar(paragraph, blankStr, false); } if (paperTemplate.getPtSealLineStudentClass()) { addTextToSidebar(paragraph, " 班級:", false); addTextToSidebar(paragraph, blankStr, false); } //裝訂線 XWPFTableCell cellLine = sidebarTable.getRow(0).getCell(1); paragraph = cellLine.getParagraphs().get(0); paragraph.setVerticalAlignment(TextAlignment.CENTER); paragraph.setAlignment(ParagraphAlignment.CENTER); // paragraph.setAlignment(ParagraphAlignment.CENTER); // paragraph.setFontAlignment(2); //String lineStr = "-----------------------------------------------"; String lineStr = "-------------------------------------------"; addTextToSidebar(paragraph, lineStr, false); addTextToSidebar(paragraph, " 密 - 封 - 線 ", false); addTextToSidebar(paragraph, lineStr, false); } private void addTextToSidebar(XWPFParagraph paragraph, String text, boolean isUnderline) { XWPFRun studentRun = paragraph.createRun(); studentRun.setText(text); studentRun.setFontSize(paperTemplate.getPtSealLineSize()); studentRun.setFontFamily(paperTemplate.getPtSealLineFamily()); if (isUnderline) { studentRun.setUnderline(UnderlinePatterns.SINGLE); } } private void addTextToSidebar(XWPFParagraph paragraph, String text, boolean isUnderline, boolean isBold) { XWPFRun studentRun = paragraph.createRun(); studentRun.setText(text); studentRun.setFontSize(paperTemplate.getPtSealLineSize()); studentRun.setFontFamily(paperTemplate.getPtSealLineFamily()); if (isBold) studentRun.setBold(true); if (isUnderline) { studentRun.setUnderline(UnderlinePatterns.SINGLE); } } /** * 設置頁腳 */ private void writeWordFooter(XWPFDocument docx) { boolean hasFoot = paperTemplate.getPtPageFootShow() && StringUtils.isNotEmpty(paperTemplate.getPtPageFootText()); boolean hasPageNum = paperTemplate.getPtPageNumShow(); if (hasFoot || hasPageNum) { XWPFHeaderFooterPolicy headerFooterPolicy = docx.getHeaderFooterPolicy(); if (headerFooterPolicy == null) headerFooterPolicy = docx.createHeaderFooterPolicy(); XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT); XWPFParagraph p = footer.getParagraphs() != null && footer.getParagraphs().size() > 0 ? footer.getParagraphs().get(0) : footer.createParagraph(); if (hasFoot) { if (StringUtils.isNotEmpty(paperTemplate.getPtPageFootAlign())) p.setAlignment(Enum.valueOf(ParagraphAlignment.class, paperTemplate.getPtPageFootAlign())); XWPFRun run = p.createRun(); run.setText(paperTemplate.getPtPageFootText()); run.setFontSize(paperTemplate.getPtPageFootSize()); if (hasPageNum) { p.setAlignment(ParagraphAlignment.LEFT); } } else { p.setAlignment(ParagraphAlignment.CENTER); } if (hasPageNum) { //設置分頁 if (hasFoot) { CTTabStop tabStop = p.getCTP().getPPr().addNewTabs().addNewTab(); tabStop.setVal(STTabJc.RIGHT); //設置位置? int twipsPerInch = 1440; tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch)); } XWPFRun run = p.createRun(); run.setFontSize(paperTemplate.getPtPageNumSize()); run.setText("第"); if (hasFoot) run.addTab(); //當前頁 begin //p.getCTP().addNewFldSimple().setInstr("PAGE \\* MERGEFORMAT"); run = p.createRun(); run.setShadow(false); run.setFontSize(paperTemplate.getPtPageNumSize()); CTFldChar fldChar = run.getCTR().addNewFldChar(); fldChar.setFldCharType(STFldCharType.Enum.forString("begin")); run.setFontSize(paperTemplate.getPtPageNumSize()); CTText ctText = run.getCTR().addNewInstrText(); ctText.setStringValue("PAGE \\* MERGEFORMAT"); ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve")); fldChar = run.getCTR().addNewFldChar(); fldChar.setFldCharType(STFldCharType.Enum.forString("end")); //當前頁 end run = p.createRun(); run.setFontSize(paperTemplate.getPtPageNumSize()); run.setText("頁 (共"); //總頁數(shù) begin run = p.createRun(); run.setFontSize(paperTemplate.getPtPageNumSize()); fldChar = run.getCTR().addNewFldChar(); fldChar.setFldCharType(STFldCharType.Enum.forString("begin")); run = p.createRun(); run.setFontSize(paperTemplate.getPtPageNumSize()); ctText = run.getCTR().addNewInstrText(); ctText.setStringValue("NUMPAGES \\* MERGEFORMAT"); ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve")); //run = p.createRun(); //run.setFontSize(paperTemplate.getPtPageNumSize()); fldChar = run.getCTR().addNewFldChar(); fldChar.setFldCharType(STFldCharType.Enum.forString("end")); //總頁數(shù) end run = p.createRun(); run.setFontSize(paperTemplate.getPtPageNumSize()); run.setText("頁)"); } } } /** * 寫入試卷信息 */ private void writePaperInfo() throws IOException, InvalidFormatException { //頂部標題 if (paperTemplate.getPtTitle() && StringUtils.isNotEmpty(verifyPaper.getVerifyPaperTopName())) { XWPFParagraph topTitle = createParagraph(paperTemplate.getPtTitleFontSize()); topTitle.setAlignment(ParagraphAlignment.CENTER); XWPFRun run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtTitleFontFamily()); run.setFontSize(paperTemplate.getPtTitleFontSize()); run.setText(verifyPaper.getVerifyPaperTopName()); run.setBold(paperTemplate.getPtTitleBold()); } //試卷標題 if (StringUtils.isNotEmpty(verifyPaper.getVerifyPaperName())) { XWPFParagraph topTitle = createParagraph(paperTemplate.getPtTitleSubFontSize()); topTitle.setAlignment(ParagraphAlignment.CENTER); XWPFRun run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtTitleSubFontFamily()); run.setFontSize(paperTemplate.getPtTitleSubFontSize()); run.setText(verifyPaper.getVerifyPaperName()); run.setBold(paperTemplate.getPtTitleSubBold()); } // 答案及標準字樣 if (includeAnswer) { XWPFParagraph topTitle = createParagraph(paperTemplate.getPtTitleSubFontSize()); topTitle.setAlignment(ParagraphAlignment.CENTER); XWPFRun run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtTitleSubFontFamily()); run.setFontSize(paperTemplate.getPtTitleSubFontSize()); run.setText("參考答案及評分標準"); } //考試信息 if (paperTemplate.getPtPaperInfoShow()) { XWPFParagraph topTitle = createParagraph(paperTemplate.getPtPaperInfoSize()); topTitle.setAlignment(ParagraphAlignment.CENTER); boolean haPre = false; if (paperTemplate.getPtShowAnswerMode()) { XWPFRun run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtPaperInfoFamily()); run.setFontSize(paperTemplate.getPtPaperInfoSize()); run.setText("考試形式:"); run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtPaperInfoFamily()); run.setFontSize(paperTemplate.getPtPaperInfoSize()); run.setText(StringUtils.format(" {} ", verifyPaper.getVpAnswerMode() == 0 ? "閉卷" : "開卷")); run.setUnderline(UnderlinePatterns.SINGLE); haPre = true; } if (paperTemplate.getPtShowAnswerTime()) { XWPFRun run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtPaperInfoFamily()); run.setFontSize(paperTemplate.getPtPaperInfoSize()); run.setText((haPre ? " " : "") + "考試時間:"); run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtPaperInfoFamily()); run.setFontSize(paperTemplate.getPtPaperInfoSize()); run.setText(StringUtils.format(" {} ", verifyPaper.getVpTotalTimeMinute())); run.setUnderline(UnderlinePatterns.SINGLE); run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtPaperInfoFamily()); run.setFontSize(paperTemplate.getPtPaperInfoSize()); run.setText("分鐘"); haPre = true; } if (paperTemplate.getPtShowAnswerTime()) { XWPFRun run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtPaperInfoFamily()); run.setFontSize(paperTemplate.getPtPaperInfoSize()); run.setText((haPre ? " " : "") + "滿分:"); run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtPaperInfoFamily()); run.setFontSize(paperTemplate.getPtPaperInfoSize()); run.setText(StringUtils.format(" {} ", verifyPaper.getVpTotalMark().stripTrailingZeros().toPlainString())); run.setUnderline(UnderlinePatterns.SINGLE); run = topTitle.createRun(); run.setFontFamily(paperTemplate.getPtPaperInfoFamily()); run.setFontSize(paperTemplate.getPtPaperInfoSize()); run.setText("分。"); haPre = true; } addNewBlankLine(docx); } //得分欄 if (paperTemplate.getPtScoreColumn()) { int colNum = 2 + verifyPaper.getVerifyPaperQtList().size(); double colWidth = 2; XWPFTable scoreTable = docx.createTable(3, colNum); scoreTable.setTableAlignment(TableRowAlign.CENTER); scoreTable.setWidth(getTwipFromCM(colWidth * colNum).intValue()); setTableBorder(scoreTable, true); for (XWPFTableRow row : scoreTable.getRows()) { row.setHeight(getTwipFromCM(1).intValue()); for (XWPFTableCell cell : row.getTableCells()) { cell.setWidth(getTwipFromCM(colWidth).toString()); } } setCellText(scoreTable.getRows().get(0).getTableCells().get(0), "題 號", paperTemplate.getPtScoreColumnFamily(), paperTemplate.getPtScoreColumnSize(), paperTemplate.getPtScoreColumnBold(), false, ParagraphAlignment.CENTER, XWPFTableCell.XWPFVertAlign.CENTER); for (int i = 0; i < verifyPaper.getVerifyPaperQtList().size(); i++) { setCellText(scoreTable.getRow(0).getCell(i + 1), this.quSortNoArr[i], paperTemplate.getPtScoreColumnFamily(), paperTemplate.getPtScoreColumnSize(), paperTemplate.getPtScoreColumnBold(), false, ParagraphAlignment.CENTER, XWPFTableCell.XWPFVertAlign.CENTER); } setCellText(scoreTable.getRow(0).getCell(colNum - 1), "總 分", paperTemplate.getPtScoreColumnFamily(), paperTemplate.getPtScoreColumnSize(), paperTemplate.getPtScoreColumnBold(), false, ParagraphAlignment.CENTER, XWPFTableCell.XWPFVertAlign.CENTER); setCellText(scoreTable.getRow(1).getCell(0), "得 分", paperTemplate.getPtScoreColumnFamily(), paperTemplate.getPtScoreColumnSize(), paperTemplate.getPtScoreColumnBold(), false, ParagraphAlignment.CENTER, XWPFTableCell.XWPFVertAlign.CENTER); setCellText(scoreTable.getRow(2).getCell(0), "評閱人", paperTemplate.getPtScoreColumnFamily(), paperTemplate.getPtScoreColumnSize(), paperTemplate.getPtScoreColumnBold(), false, ParagraphAlignment.CENTER, XWPFTableCell.XWPFVertAlign.CENTER); addNewBlankLine(docx); } if (StringUtils.isNotEmpty(paperTemplate.getPtReadme())) { XWPFTable readmeTable = docx.createTable(1, 2); readmeTable.setTableAlignment(TableRowAlign.CENTER); readmeTable.setWidth(getTwipFromCM(15).intValue()); setTableBorder(readmeTable, false); XWPFTableCell cell1 = readmeTable.getRow(0).getCell(0); cell1.setWidth(getTwipFromCM(2).toString()); XWPFParagraph paragraph = cell1.getParagraphs().get(0); paragraph.setVerticalAlignment(TextAlignment.TOP); paragraph.setAlignment(ParagraphAlignment.RIGHT); XWPFRun run = paragraph.createRun(); run.setFontSize(paperTemplate.getPtReadmeFontSize()); run.setFontFamily(paperTemplate.getPtReadmeFontFamily()); if (paperTemplate.getPtReadmeBold()) run.setBold(true); run.setText("注意:"); //右側注意事項 XWPFTableCell cell2 = readmeTable.getRow(0).getCell(1); paragraph = cell2.getParagraphs().get(0); paragraph.setSpacingLineRule(LineSpacingRule.AT_LEAST); paragraph.setVerticalAlignment(TextAlignment.TOP); paragraph.setAlignment(ParagraphAlignment.LEFT); run = paragraph.createRun(); run.setFontSize(paperTemplate.getPtReadmeFontSize()); run.setFontFamily(paperTemplate.getPtReadmeFontFamily()); if (paperTemplate.getPtReadmeBold()) run.setBold(true); run.setText(paperTemplate.getPtReadme()); addNewBlankLine(docx); } } private XWPFParagraph createParagraph(Integer fontSize) { XWPFParagraph paragraph = docx.createParagraph(); paragraph.setAlignment(ParagraphAlignment.LEFT); paragraph.setVerticalAlignment(TextAlignment.CENTER); if (fontSize != null) { setParagraphTopPadding(paragraph, fontSize); } return paragraph; } /** * 設置段落第一行頭部間隔 * 間隔為字體的一半 * * @param paragraph * @param fontSize */ private void setParagraphTopPadding(XWPFParagraph paragraph, Integer fontSize) { BigInteger space = getTwipFromPound(fontSize.doubleValue()).divide(BigInteger.valueOf(2)); paragraph.setSpacingBefore(space.intValue()); } /** * 表格設置文字 * * @param cell * @param text * @param fontFamily * @param fontSize * @param isBold * @param isUnderLine * @param align * @param vAlign */ private void setCellText(XWPFTableCell cell, String text, String fontFamily, Integer fontSize, Boolean isBold, Boolean isUnderLine, ParagraphAlignment align, XWPFTableCell.XWPFVertAlign vAlign ) { XWPFParagraph paragraph = cell.getParagraphs().get(0); if (align != null) paragraph.setAlignment(align); if (vAlign != null) cell.setVerticalAlignment(vAlign); XWPFRun run = paragraph.createRun(); run.setText(text); if (StringUtils.isNotEmpty(fontFamily)) run.setFontFamily(fontFamily); if (fontSize != null) run.setFontSize(fontSize); if (isBold != null) run.setBold(isBold); if (isUnderLine != null && isUnderLine) run.setUnderline(UnderlinePatterns.SINGLE); } /** * 添加空行 * * @param document */ private void addNewBlankLine(XWPFDocument document) { XWPFParagraph paragraph = document.createParagraph(); paragraph.createRun().setText(""); } /** * 設置題型 */ private void writeWordQts() throws IOException, InvalidFormatException { for (int i = 0; i < verifyPaper.getVerifyPaperQtList().size(); i++) { VerifyPaperQt qt = verifyPaper.getVerifyPaperQtList().get(i); //處理標題 writeWordQtTitle(qt, i); //處理試題 writeQuestionForQt(qt); } } /** * 寫入題型試題 * * @return */ private void writeWordQtTitle(VerifyPaperQt qt, Integer qtIndex) { String ext = qt.getVpQtDescription(); if (StringUtils.isEmpty(ext)) ext = StringUtils.format("(本大題{}小題,每小題{}分,共{}分)", qt.getVpQtQuNum(), qt.getVpQtQuMark().stripTrailingZeros().toPlainString(), qt.getVpQtMark().stripTrailingZeros().toPlainString()); String title = StringUtils.format("{}、{} {}", quSortNoArr[qtIndex], qt.getVerifyPaperQtName(), ext); //表格 if (paperTemplate.getPtQtScoreColumn() != null && paperTemplate.getPtQtScoreColumn()) { if (qtIndex > 1) addNewBlankLine(docx); setQtTitleScoreColumn(title); } else { XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQtTitleSize()); paragraph.setAlignment(ParagraphAlignment.LEFT); //字體左對齊 XWPFRun runText = paragraph.createRun(); runText.setBold(paperTemplate.getPtQtTitleBold()); runText.setText(title); runText.setFontSize(paperTemplate.getPtQtTitleSize().intValue()); runText.setFontFamily(paperTemplate.getPtQtTitleFamily(), XWPFRun.FontCharRange.ascii); } } /** * 添加得分欄+標題 * 創(chuàng)建表格合并行 * * @param title */ private void setQtTitleScoreColumn(String title) { BigInteger w = this.ctSectPr.getPgSz().getW(); XWPFTable pTable = docx.createTable(2, 2); pTable.setTableAlignment(TableRowAlign.LEFT); CTTblPr ctTblPr = pTable.getCTTbl().getTblPr(); ctTblPr.getTblW().setType(STTblWidth.DXA); //設置寬度 ctTblPr.getTblW().setW(w); mergeCell(pTable, 0, 1, 1); pTable.getRow(0).setHeight(getTwipFromCM(1).intValue()); pTable.getRow(1).setHeight(getTwipFromCM(1).intValue()); //得分欄 2 厘米 XWPFTableCell cellScore = pTable.getRow(0).getCell(0); cellScore.setWidth(getTwipFromCM(2).toString()); setCellText(cellScore, "得分", paperTemplate.getPtQtScoreColumnFamily(), paperTemplate.getPtQtScoreColumnSize(), true, false, ParagraphAlignment.CENTER, XWPFTableCell.XWPFVertAlign.CENTER); //標題欄 XWPFTableCell cellTitle = pTable.getRow(0).getCell(1); cellTitle.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); XWPFParagraph paragraph = cellTitle.getParagraphs().get(0); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQtTitleSize()).divide(BigInteger.valueOf(2)).intValue()); paragraph.setAlignment(ParagraphAlignment.LEFT); paragraph.setVerticalAlignment(TextAlignment.CENTER); XWPFRun runText = paragraph.createRun(); if (paperTemplate.getPtQtTitleBold() != null) runText.setBold(paperTemplate.getPtQtTitleBold()); runText.setText(title); runText.setFontSize(paperTemplate.getPtQtTitleSize().intValue()); runText.setFontFamily(paperTemplate.getPtQtTitleFamily(), XWPFRun.FontCharRange.ascii); setTableBorder(pTable, false); //設置邊框 CTTcBorders borders = CTTcBorders.Factory.newInstance(); CTBorder border = CTBorder.Factory.newInstance(); border.setVal(STBorder.SINGLE); border.setColor(rgb_black); border.setSz(BigInteger.ONE); border.setSpace(BigInteger.ZERO); borders.setLeft(border); borders.setBottom(border); borders.setRight(border); borders.setTop(border); CTTcPr ctTcPr1 = pTable.getRow(0).getCell(0).getCTTc().getTcPr(); if (ctTcPr1 == null) ctTcPr1 = pTable.getRow(0).getCell(0).getCTTc().addNewTcPr(); ctTcPr1.setTcBorders(borders); CTTcPr ctTcPr2 = pTable.getRow(1).getCell(0).getCTTc().getTcPr(); if (ctTcPr2 == null) ctTcPr2 = pTable.getRow(1).getCell(0).getCTTc().addNewTcPr(); ctTcPr2.setTcBorders(borders); } // // private void setQtTitleScoreColumn(String title) { // BigInteger w = this.ctSectPr.getPgSz().getW(); // XWPFTable pTable = docx.createTable(1, 2); // setTableBorder(pTable, false); // pTable.setTableAlignment(TableRowAlign.LEFT); // CTTblPr ctTblPr = pTable.getCTTbl().getTblPr(); // ctTblPr.getTblW().setType(STTblWidth.DXA); // //設置寬度 // ctTblPr.getTblW().setW(w); // // pTable.getRow(0).setHeight(getTwipFromCM(2).intValue()); // //得分欄 2 厘米 // XWPFTableCell cellScore = pTable.getRow(0).getCell(0); // cellScore.setWidth(getTwipFromCM(2).toString()); // setQtScoreColumnTable(cellScore); // // //標題欄 // XWPFTableCell cellTitle = pTable.getRow(0).getCell(1); // cellTitle.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); // // XWPFParagraph paragraph = cellTitle.getParagraphs().get(0); // paragraph.setAlignment(ParagraphAlignment.LEFT); // paragraph.setVerticalAlignment(TextAlignment.CENTER); // XWPFRun runText = paragraph.createRun(); // if (paperTemplate.getPtQtTitleBold() != null) runText.setBold(paperTemplate.getPtQtTitleBold()); // runText.setText(title); // runText.setFontSize(paperTemplate.getPtQtTitleSize().intValue()); // runText.setFontFamily(paperTemplate.getPtQtTitleFamily(), XWPFRun.FontCharRange.ascii); // } /** * 合并單元格 * * @param table 表格對象 * @param beginRowIndex 開始行索引 * @param endRowIndex 結束行索引 * @param colIndex 合并列索引 */ private void mergeCell(XWPFTable table, int beginRowIndex, int endRowIndex, int colIndex) { if (beginRowIndex == endRowIndex || beginRowIndex > endRowIndex) { return; } //合并行單元格的第一個單元格 CTVMerge startMerge = CTVMerge.Factory.newInstance(); startMerge.setVal(STMerge.RESTART); //合并行單元格的第一個單元格之后的單元格 CTVMerge endMerge = CTVMerge.Factory.newInstance(); endMerge.setVal(STMerge.CONTINUE); CTTc ctTc = table.getRow(beginRowIndex).getCell(colIndex).getCTTc(); (ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr()).setVMerge(startMerge); for (int i = beginRowIndex + 1; i <= endRowIndex; i++) { ctTc = table.getRow(i).getCell(colIndex).getCTTc(); (ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr()).setVMerge(endMerge); } } /** * 獲取得分欄 * * @return */ private void setQtScoreColumnTable(XWPFTableCell cell) { XWPFTable xwpfTable = docx.createTable(2, 1);// new XWPFTable(CTTbl.Factory.newInstance(), cell, 2, 1);// cell.insertTable(0, xwpfTable); logger.info("表格:{}", cell.getTables().size()); xwpfTable = cell.getTables().get(0); xwpfTable.setTableAlignment(TableRowAlign.CENTER); xwpfTable.setWidth(getTwipFromCM(2).toString()); //設置邊框 setTableBorder(xwpfTable, true); XWPFTableRow row1 = xwpfTable.getRow(0); row1.setHeight(getTwipFromCM(1).intValue()); XWPFTableCell cell1 = row1.getCell(0); cell1.setWidth(getTwipFromCM(2).toString()); cell1.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); XWPFParagraph p = cell1.getParagraphs().get(0); p.setAlignment(ParagraphAlignment.CENTER); //字體左對齊 p.setVerticalAlignment(TextAlignment.CENTER); XWPFRun rt = p.createRun(); rt.setBold(paperTemplate.getPtQtScoreColumnBold()); rt.setFontSize(paperTemplate.getPtScoreColumnSize()); rt.setFontFamily(paperTemplate.getPtScoreColumnFamily(), XWPFRun.FontCharRange.ascii); rt.setText("得分"); XWPFTableRow row2 = xwpfTable.getRow(1); row2.setHeight(getTwipFromCM(1).intValue()); } /** * 寫入題型試題 * * @return */ private void writeQuestionForQt(VerifyPaperQt qt) throws IOException, InvalidFormatException { for (VerifyPaperQu qu : qt.getVerifyPaperQuList()) { getQuLines(qu, qu.getVpQuIndexQt()); } } /** * 將文字寫入段落 * * @param paragraph * @param line * @throws IOException * @throws InvalidFormatException */ private void writeWordQuLine(XWPFParagraph paragraph, String line) throws IOException, InvalidFormatException { for (LineIncludeImg lineImg : getContainImgArr(line)) { if (StringUtils.isEmpty(lineImg.text) && lineImg.image == null) continue; String imgLine = lineImg.text; String picExtension = ""; if (imgLine == null) imgLine = ""; byte[] imgBytes = null; if (lineImg.image != null) { imgLine = ""; imgBytes = lineImg.image; } else if (imgLine.startsWith("data:image/")) { String base64Str = imgLine.substring(imgLine.indexOf(',') + 1); picExtension = imgLine.substring(imgLine.indexOf('/') + 1, imgLine.indexOf(';')); imgBytes = Base64.decode(base64Str); for (int i = 0; i < imgBytes.length; ++i) { if (imgBytes[i] < 0) { imgBytes[i] += 256; } } imgLine = ""; } if (imgBytes != null) { InputStream inputStream = new ByteArrayInputStream(imgBytes); BufferedImage image = ImageIO.read(inputStream); int width = image.getWidth(); int height = image.getHeight(); inputStream.close(); XWPFRun picRun = paragraph.createRun(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String picName = simpleDateFormat.format(DateUtils.getNowDate()) + "." + picExtension; InputStream picStream = new ByteArrayInputStream(imgBytes); //picRun.addPicture(picStream, getPictureType(picExtension), picName, width, height); double scaling = 1.0; //2)2023-06-13 優(yōu)化 若圖片寬度超過word的最大寬值,圖片將會變形、所以通過等比縮小來處理 word文檔中:寬大最大650px(17厘米) BigDecimal maxWidthWord = new BigDecimal(650); BigDecimal widthDecimal = new BigDecimal(width); if (widthDecimal.compareTo(maxWidthWord) > 0) { BigDecimal divide = maxWidthWord.divide(widthDecimal, 2, RoundingMode.HALF_UP); scaling = divide.doubleValue(); picRun.addPicture(picStream, getPictureType(picExtension), picName, Units.toEMU(width - width * scaling), Units.toEMU(height - height * scaling)); } else { picRun.addPicture(picStream, getPictureType(picExtension), picName, Units.toEMU(width), Units.toEMU(height)); } CTInline inline = picRun.getCTR().getDrawingList().get(0).getInlineArray(0); inline.getDocPr().setId(1L); //id必須從1開始 解決打開文檔時 報錯(NPOI v2.4 已修復) //此處是否可關閉 picStream.close(); } else if (StringUtils.isNotEmpty(imgLine)) { //創(chuàng)建 run對象 XWPFRun runText = paragraph.createRun(); runText.setText(imgLine); runText.setBold(paperTemplate.getPtQuStemBold()); runText.setFontSize(paperTemplate.getPtQuStemSize()); runText.setFontFamily(paperTemplate.getPtQuStemFamily(), XWPFRun.FontCharRange.ascii); } } } /** * 獲取一道試題段落 * * @param qe * @param qIndex * @return */ private void getQuLines(VerifyPaperQu qe, Integer qIndex) throws IOException, InvalidFormatException { if (qe.getQuestionIsMultipleStem() == null || !qe.getQuestionIsMultipleStem()) { //無子試題 //list.addAll(); getSingleLines(qe, qIndex); } else { //有子試題 getMultipleLines(qe, qIndex); } } /** * 獲取單題面行 * * @param qe * @return */ private void getSingleLines(VerifyPaperQu qe, Integer qIndex) throws IOException, InvalidFormatException { VerifyPaperQuStem quStem = qe.getVerifyPaperQuStem(); //題面 String stem = StringUtils.getTextFromHTML(quStem.getQuStem(), imgRegex); String line = StringUtils.format("{}. ", qIndex); XWPFParagraph stemParagraph = createParagraph(paperTemplate.getPtQuStemSize()); //試題題號加粗 XWPFRun run = stemParagraph.createRun(); run.setText(line); run.setFontSize(paperTemplate.getPtQuStemSize()); run.setBold(true); writeWordQuLine(stemParagraph, stem); //選項 for (int i = 0; i < 10; i++) { char c = ((char) (65 + i)); String optionTag = String.valueOf(c).toUpperCase(); String pName = StringUtils.format("quOption{}{}", optionTag, i + 1); String option = ReflectUtils.invokeGetter(quStem, pName); if (StringUtils.isEmpty(option)) break; option = StringUtils.getTextFromHTML(option, imgRegex); XWPFParagraph optionParagraph = createParagraph(paperTemplate.getPtQuStemSize()); optionParagraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(optionParagraph, StringUtils.format("{}、{}", optionTag, option)); } //答案 if (includeAnswer && StringUtils.isNotEmpty(quStem.getQuAnswer())) { String answer = StringUtils.getTextFromHTML(quStem.getQuAnswer(), imgRegex); XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.AnswerStartWord, answer)); } //評分點,填空題不顯示評分點 if (includeAnswer && StringUtils.isNotEmpty(quStem.getQuJudgePoint()) && !qe.getQuestionIsFillBlank()) { JudgeRule judgeRule = JSONObject.parseObject(quStem.getQuJudgePoint(), JudgeRule.class); if (judgeRule.getItems() != null && judgeRule.getItems().size() > 0) { String points = StringUtils.joinWith(importRule.PointSeparateWord, judgeRule.getItems().get(0).getPoints().stream().map(p -> p.getAnswer()).toArray(String[]::new)); XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.PointStartWord, points)); } } //評析 if (includeAnswer && StringUtils.isNotEmpty(quStem.getQuAnalyse())) { String answer = StringUtils.getTextFromHTML(quStem.getQuAnalyse(), imgRegex); XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.AnalyseStartWord, answer)); } if (includeAnswer) { //難度 XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.DifficultyStartWord, qe.getDifficulty())); } //知識點 if (includeAnswer && StringUtils.isNotEmpty(qe.getKnowledgeList())) { //須處理關系 ????????? //list.add(StringUtils.format("{}{}", importRule.KnowledgeStartWord,qe.getKnowledgeList().)); } //年份 if (includeAnswer) { XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.YearStartWord, qe.getQuestionYear())); } //來源 if (includeAnswer && StringUtils.isNotEmpty(qe.getQuestionOrigin())) { XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.OriginStartWord, qe.getQuestionOrigin())); } docx.createParagraph().createRun().setText("\n"); //添加一個空行 //list.add("\n"); if (!includeAnswer && qe.getQuestionIsSubjective()) { //自適應高度計算,根據(jù)答案文字數(shù)量 } } /** * 獲取多題面試題行 * * @param qe * @return */ private void getMultipleLines(VerifyPaperQu qe, Integer qIndex) throws IOException, InvalidFormatException { VerifyPaperQuStem quStem = qe.getVerifyPaperQuStem(); //題面 String stem = StringUtils.getTextFromHTML(quStem.getQuStem(), imgRegex); String line = (StringUtils.format("{}.", qIndex.toString())); XWPFParagraph stemParagraph = createParagraph(paperTemplate.getPtQuStemSize()); //試題題號加粗 XWPFRun run = stemParagraph.createRun(); run.setText(line); run.setFontSize(paperTemplate.getPtQuStemSize()); run.setBold(true); writeWordQuLine(stemParagraph, stem); //子試題 for (int i = 0; i < qe.getSubQuestionList().size(); i++) { getSubQuLines(qe.getSubQuestionList().get(i), i + 1); } //評析 if (includeAnswer && StringUtils.isNotEmpty(quStem.getQuAnalyse())) { String answer = StringUtils.getTextFromHTML(quStem.getQuAnalyse(), imgRegex); XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.AnalyseStartWord, answer)); } //難度 if (includeAnswer) { XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.DifficultyStartWord, qe.getDifficulty())); //知識點 if (includeAnswer && StringUtils.isNotEmpty(qe.getKnowledgeList())) { //list.add(StringUtils.format("{}{}", importRule.KnowledgeStartWord, qe.getKnowledgeName())); } //年份 paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.YearStartWord, qe.getQuestionYear())); //來源 if (includeAnswer && StringUtils.isNotEmpty(qe.getQuestionOrigin())) { paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize() * 2).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.OriginStartWord, qe.getQuestionOrigin())); } } //添加一個空行 this.addNewBlankLine(docx); } /** * 獲取子題面行 * * @param subQe * @return */ private void getSubQuLines(VerifyPaperQu subQe, Integer qSubIndex) throws IOException, InvalidFormatException { //題面 VerifyPaperQuStem quStem = subQe.getVerifyPaperQuStem(); String stem = StringUtils.getTextFromHTML(quStem.getQuStem(), imgRegex); String line = (StringUtils.format("{}). ", qSubIndex)); XWPFParagraph stemParagraph = createParagraph(paperTemplate.getPtQuStemSize()); stemParagraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize()).intValue()); //試題題號加粗 XWPFRun run = stemParagraph.createRun(); run.setText(line); run.setFontSize(paperTemplate.getPtQuStemSize()); run.setBold(true); writeWordQuLine(stemParagraph, stem); //選項 for (int i = 0; i < 10; i++) { char c = ((char) (65 + i)); String optionTag = String.valueOf(c).toUpperCase(); String pName = StringUtils.format("quOption{}{}", optionTag, i + 1); String option = ReflectUtils.invokeGetter(quStem, pName); if (StringUtils.isEmpty(option)) break; option = StringUtils.getTextFromHTML(option, imgRegex); XWPFParagraph optionParagraph = createParagraph(paperTemplate.getPtQuStemSize()); optionParagraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize()).intValue()); writeWordQuLine(optionParagraph, StringUtils.format("{}、{}", optionTag, option)); } //答案 if (includeAnswer && StringUtils.isNotEmpty(quStem.getQuAnswer())) { String answer = StringUtils.getTextFromHTML(quStem.getQuAnswer(), imgRegex); XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize()).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.AnswerStartWord, answer)); } //評分點 if (includeAnswer && StringUtils.isNotEmpty(quStem.getQuJudgePoint()) && !subQe.getQuestionIsFillBlank()) { JudgeRule judgeRule = JSONObject.parseObject(quStem.getQuJudgePoint(), JudgeRule.class); if (judgeRule.getItems() != null && judgeRule.getItems().size() > 0) { String points = StringUtils.joinWith(importRule.PointSeparateWord, judgeRule.getItems().get(0).getPoints().stream().map(p -> p.getAnswer()).toArray(String[]::new)); XWPFParagraph paragraph = createParagraph(paperTemplate.getPtQuStemSize()); paragraph.setIndentationLeft(getTwipFromPound(paperTemplate.getPtQuStemSize()).intValue()); writeWordQuLine(paragraph, StringUtils.format("{}{}", importRule.PointStartWord, points)); } } //添加一個空行 this.addNewBlankLine(docx); if (!includeAnswer && subQe.getQuestionIsSubjective()) { //自適應高度計算,根據(jù)答案文字數(shù)量 } } private boolean isMatchWithRegex(String regex, String input) { if (StringUtils.isEmpty(regex)) return false; return Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matcher(input).find(); } /** * 通過圖片分割 * * @param str * @return */ public List<LineIncludeImg> getContainImgArr(String str) { String imgReg = "<img\\s*/?[^>]*>"; List<LineIncludeImg> list = new ArrayList<>(); if (!isMatchWithRegex(imgReg, str)) { list.add(new LineIncludeImg(str)); return list; } String getSrcReg = "\\bsrc\\b\\s*=\\s*['\"]?([^'\"]*)['\"]?";// "<img.*src=('|\")(.+?)('|\").*/?[^>]*>"; String removeSrcReg = "(^\\bsrc\\b\\s*=\\s*['\"]?)|(['\"]?$)"; //讀取base64 Matcher matcher = Pattern.compile(imgReg, Pattern.CASE_INSENSITIVE).matcher(str); int _index = 0; //2023-06-13 支持多個圖片 while (matcher.find()) { if (matcher.start() > _index) { list.add(new LineIncludeImg(str.substring(_index, matcher.start()))); } _index = matcher.end(); String group = str.substring(matcher.start(), matcher.end()); Matcher mSrc = Pattern.compile(getSrcReg, Pattern.CASE_INSENSITIVE).matcher(group); if (mSrc.find()) { String srcText = mSrc.group(); String src = srcText.replaceAll(removeSrcReg, ""); if (src.startsWith("data:image/")) { list.add(new LineIncludeImg(src)); } else if (StringUtils.ishttp(src)) { String extend = FileTypeUtils.getFileType(src); byte[] srcBase64 = ImageUtils.getImage(src);// UtilTools.getImageDataFromServer(src); if (StringUtils.isEmpty(extend)) extend = FileTypeUtils.getFileExtendName(srcBase64); //下載圖片獲取base64HttpUtils list.add(new LineIncludeImg(srcBase64, extend)); } } } if (_index < str.length()) { list.add(new LineIncludeImg(str.substring(_index))); } return list; } /** * 獲取圖片類型 * * @param picExtension * @return */ public int getPictureType(String picExtension) { switch (picExtension.toUpperCase()) { case "EMF": return 2; case "WMF": return 3; case "PICT": return 4; case "JPEG": return 5; case "PNG": return 6; case "DIB": return 7; case "GIF": return 8; case "TIFF": return 9; case "EPS": return 10; case "BMP": return 11; case "WPG": return 12; default: return 5; } } public class LineIncludeImg { public LineIncludeImg(byte[] image, String extend) { this.image = image; this.extend = extend; } public LineIncludeImg(String text) { this.text = text; } /** * 文本內容 */ public String text; //圖片二進制數(shù)據(jù) public byte[] image; //擴展名,不帶 . public String extend; } /** * 每厘米567緹 */ private double teePerCM = 567; /** * 每厘米28.35磅 */ private double poundPerCm = 28.35; /** * 根據(jù)磅,獲取緹 * * @return */ private BigInteger getTwipFromPound(double pound) { Double d = pound * teePerCM / poundPerCm; return BigInteger.valueOf(d.longValue()); } /** * 根據(jù)厘米,獲取緹 * * @param cm * @return */ private BigInteger getTwipFromCM(double cm) { Double d = cm * teePerCM; return BigInteger.valueOf(d.longValue()); } private void setTableBorder(XWPFTable table, boolean hasBorder) { if (hasBorder) { table.setTopBorder(XWPFTable.XWPFBorderType.SINGLE, 1, 0, rgb_black); table.setRightBorder(XWPFTable.XWPFBorderType.SINGLE, 1, 0, rgb_black); table.setLeftBorder(XWPFTable.XWPFBorderType.SINGLE, 1, 0, rgb_black); table.setBottomBorder(XWPFTable.XWPFBorderType.SINGLE, 1, 0, rgb_black); table.setInsideVBorder(XWPFTable.XWPFBorderType.SINGLE, 1, 0, rgb_black); table.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE, 1, 0, rgb_black); } else { table.setLeftBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, ""); table.setRightBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, ""); table.setTopBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, ""); table.setBottomBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, ""); table.setInsideHBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, ""); table.setInsideVBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, ""); } } /** * 獲取默認模板 * * @return */ public static PaperTemplate getDefaultPaperTemplate() { PaperTemplate paperTemplate = new PaperTemplate(); paperTemplate.setPtFooterMargin(BigDecimal.ZERO); paperTemplate.setPaperTemplateName("默認模板配置"); paperTemplate.setPaperTemplateCode("default-template"); paperTemplate.setPtPageSize("A4"); paperTemplate.setPtDirection(0); paperTemplate.setPtColumNum(1); paperTemplate.setPtEnFontFamily("");//Helvetica paperTemplate.setPtTitle(true); paperTemplate.setPtTitleBold(true); paperTemplate.setPtTitleFontFamily("黑體"); paperTemplate.setPtTitleFontSize(18); paperTemplate.setPtTitleSub(""); paperTemplate.setPtTitleSubBold(true); paperTemplate.setPtTitleSubFontFamily("黑體"); paperTemplate.setPtTitleSubFontSize(18); paperTemplate.setPtPaperInfoShow(true); paperTemplate.setPtPaperInfoFamily("黑體"); paperTemplate.setPtPaperInfoSize(12); paperTemplate.setPtPaperInfoBold(false); paperTemplate.setPtShowAnswerMode(true); paperTemplate.setPtShowAnswerTime(true); paperTemplate.setPtShowPaperMark(true); paperTemplate.setPtScoreColumn(true); paperTemplate.setPtScoreColumnFamily("宋體"); paperTemplate.setPtScoreColumnSize(12); paperTemplate.setPtScoreColumnBold(false); paperTemplate.setPtReadme(""); paperTemplate.setPtReadmeBold(false); paperTemplate.setPtReadmeFontFamily("宋體"); paperTemplate.setPtReadmeBold(false); paperTemplate.setPtReadmeFontSize(12); paperTemplate.setPtScoreColumn(true); paperTemplate.setPtScoreColumnBold(false); paperTemplate.setPtScoreColumnFamily("宋體"); paperTemplate.setPtScoreColumnSize(12); paperTemplate.setPtQtScoreColumn(true); paperTemplate.setPtQtScoreColumnBold(true); paperTemplate.setPtQtScoreColumnFamily("宋體"); paperTemplate.setPtQtScoreColumnSize(12); paperTemplate.setPtQtTitleBold(true); paperTemplate.setPtQtTitleFamily("宋體"); paperTemplate.setPtQtTitleSize(12); paperTemplate.setPtQuStemBold(false); paperTemplate.setPtQuStemFamily("宋體"); paperTemplate.setPtQuStemSize(11); paperTemplate.setPtMarginTop(BigDecimal.valueOf(2.54)); paperTemplate.setPtMarginBottom(BigDecimal.valueOf(2.54)); paperTemplate.setPtMarginLeft(BigDecimal.valueOf(3.18)); paperTemplate.setPtMarginRight(BigDecimal.valueOf(3.18)); paperTemplate.setPtPageHeadShow(false); paperTemplate.setPtHeaderMargin(BigDecimal.ZERO); paperTemplate.setPtPageHeadFontFamily("宋體"); paperTemplate.setPtPageHeadSize(11); paperTemplate.setPtPageHeadText(""); paperTemplate.setPtPageHeadAlign("center"); paperTemplate.setPtPageFootShow(false); paperTemplate.setPtFooterMargin(BigDecimal.ZERO); paperTemplate.setPtPageFootFontFamily("宋體"); paperTemplate.setPtPageFootSize(11); paperTemplate.setPtPageFootText(""); paperTemplate.setPtPageFootAlign("left"); paperTemplate.setPtPageNumShow(true); paperTemplate.setPtPageNumAlign("center"); paperTemplate.setPtPageNumFontFamily("宋體"); paperTemplate.setPtPageNumSize(9); paperTemplate.setPtSealLineShow(true); paperTemplate.setPtSealLineType("once"); paperTemplate.setPtSealLineFamily("宋體"); paperTemplate.setPtSealLineSize(12); paperTemplate.setPtSealLineStudentName(true); paperTemplate.setPtSealLineStudentCode(true); paperTemplate.setPtSealLineStudentCollege(true); paperTemplate.setPtSealLineStudentGrade(true); paperTemplate.setPtSealLineStudentSpecialty(true); paperTemplate.setPtSealLineStudentDepartment(false); paperTemplate.setPtSealLineStudentClass(false); return paperTemplate; } }
到此這篇關于java使用apache.poi導出word文件的示例代碼的文章就介紹到這了,更多相關java導出word文件內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springcloud使用profile實現(xiàn)多環(huán)境配置方式
這篇文章主要介紹了springcloud使用profile實現(xiàn)多環(huán)境配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03Spring?Boot中使用Spring?Retry重試框架的操作方法
這篇文章主要介紹了Spring?Retry?在SpringBoot?中的應用,介紹了RetryTemplate配置的時候,需要設置的重試策略和退避策略,需要的朋友可以參考下2022-04-04