java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java使用poi生成简单word文档并导出

Java如何使用poi生成简单word文档并导出

作者:编程经验分享

这篇文章主要介绍了Java如何使用poi生成简单word文档并导出问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

问题

项目中需要将业务数据制成表格并插入word文档中,同时还需向word文档中插入图片,最后导出word文档。

如何解决

基于 poi 写了一个通用的doc操作类,支持插入表格和图片,最后导出。

代码

pom

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.5</version>
        </dependency>

doc操作类

public class PoiDocDo {

    XWPFDocument xDoc;
    String name;

    public static PoiDocBuilder builder() { return new PoiDocBuilder();}

    public PoiDocDo(PoiDocBuilder builder) {
        xDoc = new XWPFDocument();
        name = builder.name;
    }

    public static class PoiDocBuilder {
        String name = "default";
        public PoiDocDo build() {
            return new PoiDocDo(this);
        }

        public PoiDocBuilder name(String name) {
            this.name = name;
            return this;
        }
    }

    public PoiDocDo insertParagraph(String text) {
        XWPFParagraph xPara = xDoc.createParagraph();
        xPara.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun run = xPara.createRun();
        run.setFontSize(20);
        run.setText(text);
        run.addCarriageReturn();

        return this;
    }

    /**
     * 往文档中插入表格
     *
     * @param columns 列头
     * @param rows 内容行
     */
    public PoiDocDo insertTable(List<Map<String, String>> columns,
                                List<Map<String, Object>> rows) {
        XWPFTable xTable = xDoc.createTable(rows.size() + 1, columns.size());
        centerTableContent(xTable, columns.size());

        XWPFTableRow columnNameRow = xTable.getRow(0);
        List<String> columnFields = new ArrayList<>();
        Map<String, String> columnMap;
        for (int i = 0; i < columns.size(); i++) {
            columnMap = columns.get(i);
            columnNameRow.getCell(i).setText(columnMap.get("name"));
            columnFields.add(columnMap.get("field"));
        }
        XWPFTableRow contentRow;
        Map<String, Object> rowMap;
        for (int i = 1; i <= rows.size(); i++) {
            contentRow = xTable.getRow(i);
            rowMap = rows.get(i - 1);
            for (int j = 0; j < columnFields.size(); j++) {
                contentRow.getCell(j).setText(
                        rowMap.getOrDefault(columnFields.get(j), "").toString());
            }
        }
        return this;
    }

    /**
     * 表格内容居中,此方法为依次居中每个表格的内容
     *
     * @param xTable 表格
     */
    private void centerTableContent(XWPFTable xTable, int numberOfColumns) {
        for (int i = 0; i < xTable.getNumberOfRows(); i++) {
            for (int j = 0; j < numberOfColumns; j++) {
                XWPFTableCell cell = xTable.getRow(i).getCell(j);
                CTTc cttc = cell.getCTTc();
                CTTcPr ctPr = cttc.addNewTcPr();
                ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
                cttc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
            }
        }
    }

    public PoiDocDo insertImage(List<Map<String, String>> imageInfoList) {
        XWPFParagraph xPara;
        XWPFRun run;
        String imageName, imageData;
        byte[] bytes;

        for (Map<String, String> imageInfo : imageInfoList) {
            imageName = imageInfo.get("imageName");
            imageData = imageInfo.get("imageData");
            bytes = Base64.getDecoder().decode(imageData);

            xPara = xDoc.createParagraph();
            xPara.setAlignment(ParagraphAlignment.LEFT);
            run = xPara.createRun();
            run.setFontSize(20);
            run.setText(imageName);
            run.addCarriageReturn();
            try {
                run.addPicture(new ByteArrayInputStream(bytes), XWPFDocument.PICTURE_TYPE_JPEG,
                        imageName, Units.toEMU(414), Units.toEMU(284));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return this;
    }

    public void export(OutputStream outputStream) {
        try (OutputStream os = outputStream) {
            xDoc.write(os);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void export(String desktopPath) {
        String docName = (desktopPath + "\\" + name).replaceAll("\\\\+", "/");
        try(OutputStream os = Files.newOutputStream(Paths.get(String.format("%s.docx", docName)))) {
            xDoc.write(os);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

使用示例

class PoiDocDoTest {

    @Test
    public void test() throws IOException {
        PoiDocDo domainObj = PoiDocDo.builder().name("myDoc").build();

        List<Map<String, String>> images = new ArrayList<>();
        Map<String, String> imageMap = new HashMap<>();
        images.add(imageMap);
        imageMap.put("imageName", "test");
        InputStream inputStream = Files.newInputStream(Paths.get("C:\\Users\\XXX\\Desktop\\XXX.png"));
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[16384];
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }
        imageMap.put("imageData", Base64.getEncoder().encodeToString(buffer.toByteArray()));

        List<Map<String, String>> columns = new ArrayList<>();
        Map<String, String> column = new HashMap<>();
        columns.add(column);
        column.put("name", "colum1");
        column.put("field", "field1");

        List<Map<String, Object>> rows = new ArrayList<>();
        Map<String, Object> row = new HashMap<>();
        rows.add(row);
        row.put("field1", "abc");

        domainObj.insertParagraph("This is a paragraph")
                .insertParagraph("picture under me")
                .insertImage(images)
                .insertTable(columns, rows)
                .export("C:\\Users\\XXX\\Desktop");
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文