使用Apache POI导出Word文件

28,929次阅读
没有评论

共计 43975 个字符,预计需要花费 110 分钟才能阅读完成。

本文将介绍如何使用 Java 和 Apache POI 库将试卷导出为 Word 文件,并提供打印、装订等功能。同时,将展示实现代码以及效果图。

Apache POI 到处 word 文件

Apache POI 是一个开源的 Java 库,用于操作各种 Microsoft Office 格式的文档,包括 Word、Excel 和 PowerPoint。在本文中,我们将介绍如何使用 Apache POI 来导出 Word 文件,并实现打印和装订功能。

功能说明

我们的目标是将试卷数据导出为 Word 文档,以便用户可以方便地打印和装订。下面是我们要实现的功能:

  1. 将试卷数据通过 Apache POI 库导出为 Word 文件。

  2. Word 文档应该具有良好的格式和布局,以确保打印效果良好。

  3. 文档的页眉和页脚应该包含相关信息,例如试卷标题和页码。

  4. 用户应该能够选择打印选项,并进行必要的页面设置。

  5. 用户还可以选择将导出的 Word 文档进行装订,以便更方便携带和存储。

实现步骤

以下是实现以上功能的基本步骤:

  1. 导入依赖:在项目的构建文件中添加 Apache POI 库的依赖项,以便能够使用其提供的 API。

  2. 创建试卷模板:使用 Word 处理软件(如 Microsoft Word)创建一个试卷模板,包括适当的格式、样式和布局。这个模板将用作导出的 Word 文档的基础。

  3. 编写 Java 代码:使用 Apache POI 的 API 来读取试卷数据,并将其填充到试卷模板中。这涉及到创建文档对象、段落、表格、样式等,以确保最终生成的 Word 文档符合要求。

  4. 添加页眉和页脚:使用 Apache POI 的 API,在文档中添加适当的页眉和页脚信息,例如试卷标题和页码。

  5. 实现打印功能:在导出的 Word 文档中添加打印选项,使用户可以选择打印设置,如纸张大小、边距等。这可以通过添加相应的表单字段或设置文档属性来完成。

  6. 实现装订功能:为了方便用户携带和存储试卷,我们可以添加一个装订选项。这可以是一个简单的复选框,让用户选择是否需要装订导出的 Word 文档。

  7. 测试和调试:在导出功能实现后,进行全面的测试,并根据需要进行调试和优化。

简单示例代码

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;

import java.io.FileOutputStream;
import java.math.BigInteger;

public class WordExporter {public static void main(String[] args) {
        try {
            // 创建文档对象
            XWPFDocument document = new XWPFDocument();

            // 添加页眉
            CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
            XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(document, sectPr);
            XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);

            // 设置页眉内容
            XWPFParagraph headerParagraph = header.createParagraph();
            XWPFRun headerRun = headerParagraph.createRun();
            headerRun.setText("试卷标题");

            // 创建段落对象
            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun run = paragraph.createRun();

            // 设置段落内容
            run.setText("这是一份试卷的内容");

            // 添加页脚
            XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT);

            // 设置页脚内容
            XWPFParagraph footerParagraph = footer.createParagraph();
            XWPFRun footerRun = footerParagraph.createRun();
            footerRun.setText("页码:");

            // 实现打印功能
            CTPageMar pageMar = sectPr.addNewPgMar();
            pageMar.setLeft(BigInteger.valueOf(720L));
            pageMar.setRight(BigInteger.valueOf(720L));
            pageMar.setTop(BigInteger.valueOf(720L));
            pageMar.setBottom(BigInteger.valueOf(720L));

            // 实现装订功能
            boolean needBinding = true;
            if (needBinding) {CTDocProtect protection = document.getDocument().addNewDocumentProtection();
                protection.setEnforcement(true);
                protection.setEdit(STDocProtect.READ_ONLY);
                protection.setFormatting(STDocProtect.READ_ONLY);
                protection.setEnforceComments(STDocProtect.COMMENTS_READ_ONLY);
                protection.setEnforceTrackedChanges(STDocProtect.READ_ONLY);
            }

            // 保存文档
            FileOutputStream out = new FileOutputStream("试卷.docx");
            document.write(out);
            out.close();

            System.out.println("Word 文件导出成功!");
        } catch (Exception e) {System.out.println("导出 Word 文件时发生错误:" + e.getMessage());
        }
    }
}

扩展示例

当然我们 往往 都需要比较复杂的功能。

例如:将试卷导出 word,并可以打印,装订。

效果图

使用 Apache POI 导出 Word 文件效果图

完整示例代码

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);
    }


    /**
     * 验证相关数据
     *
     * @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);
        }
    }

    /**
     * 试题数据写入文档
     */
    private R> writeWord() throws IOException, InvalidFormatException {R r = createDocxTemplate();
        if (!r.isSuccess()) return R.fail(r.getMsg());
        docx = r.getData();
        writePaperInfo();
        writeWordQts();
        return R.ok();}

    /**
     * 制作模板
     * 模板各种设置
     *
     * @return
     */
    private R 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":
                    // 奇数页
                    header = headerFooterPolicy.createHeader(STHdrFtr.DEFAULT);
                    docx.setEvenAndOddHeadings(true);
                    break;
                case "even":
                    // 偶数页
                    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();
        // 创建一个
        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));
        // 创建一个侧边栏
        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, "专业:", 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("页(共");

                // 总页数 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"));
                // 总页数 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  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);
        }
    }

    /**
     * 添加得分栏 + 标题
     * 创建表格合并行
     *
     * @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  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)) {
                // 创建 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  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()) {// 自适应高度计算,根据答案文字数量}
    }

    /**
     * 获取多题面试题行
     *
     * @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  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()) {// 自适应高度计算,根据答案文字数量}
    }

    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 getContainImgArr(String str) {String imgReg = "]*>";
        List list = new ArrayList();
        if (!isMatchWithRegex(imgReg, str)) {list.add(new LineIncludeImg(str));
            return list;
        }
        String getSrcReg = "\bsrc\b\s*=\s*['"]?([^'"]*)['"]?";//"]*>";
        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 

感谢分享

作者:javacoffeenet
扩展示例来源:https://www.cnblogs.com/javacoffeenet/p/17560899.html文章来源地址 https://www.toymoban.com/diary/java/481.html

到此这篇关于使用 Apache POI 导出 Word 文件的文章就介绍到这了, 更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持 TOY 模板网!

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于1970-01-01发表,共计43975字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)