动态导出word

这篇具有很好参考价值的文章主要介绍了动态导出word。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

import lombok.Data;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.List;

/**
 * 动态word生成
 */
@Data
public class WordUtil {
    //标题
    private String tableName;

    private List<Directory> directory;

    @lombok.Data
    static class Directory {
        //目录缩进层级
        private int isHierarchy;
        //01 :表格,02,文本,03附件
        private String type;
        //type为02时直接赋值
        private String text;
        //数据
        private List<Data> data;

    }

    @lombok.Data
    static class Data {
        //数据
        private List<String[]> values;
        //水平合并单元格
        private String colSpan;
        //垂直合并单元格
        private String rowSpan;

    }



    public static void Word(WordUtil map, HttpServletResponse response) throws IOException {
        OutputStream outputStream = null;
        try {
            //创建word文档对象
            XWPFDocument document = new XWPFDocument();
            if (StringUtil.isNotEmpty(map.getTableName())) {
                //这行代码是创建标题
                XWPFParagraph title = document.createParagraph();
                XWPFRun titleRun = title.createRun();
                title.setAlignment(ParagraphAlignment.valueOf(STJc.INT_CENTER));
                titleRun.setFontSize(20);
                titleRun.setFontFamily("宋体");
                titleRun.setBold(true);
                titleRun.setText(map.getTableName());
                titleRun.addBreak(); //换行
            }
            //获取数据
            List<Directory> list = map.getDirectory();
            if (ListUtil.isNotEmpty(list)) {
                for (int i = 0; i < list.size(); i++) {
                    //目录缩进层级
                    int isHierarchy = list.get(i).getIsHierarchy();
                    //01 :表格,02,文本,03附件
                    String type = list.get(i).getType();
                    String text = list.get(i).getText();
                    //data
                    List<Data> data = list.get(i).getData();
                    if ("01".equals(type)) {
                        if (ListUtil.isEmpty(data)) {
                            continue;
                        }
                        List<String[]> length = data.get(0).getValues();
                        //创建表格的第一步
                        XWPFTable table = document.createTable(data.size(), length.get(0).length);
                        CTTblPr tablePr = table.getCTTbl().addNewTblPr();
                        CTTblWidth width = tablePr.addNewTblW();
                        width.setW(BigInteger.valueOf(8000));
                        width.setType(STTblWidth.DXA);
                        for (int i1 = 0; i1 < data.size(); i1++) {
                            if (StringUtil.isNotEmpty(data.get(i1).getColSpan())) {
                                String[] colSpans = data.get(i1).getColSpan().split(",");
                                if (colSpans.length > 0) {
                                    //水平合并单元格
                                    mergeCellsHorizontal(table, Integer.parseInt(colSpans[0]), Integer.parseInt(colSpans[1]), Integer.parseInt(colSpans[2]));
                                }
                            }
                            if (StringUtil.isNotEmpty(data.get(i1).getRowSpan())) {
                                String[] rowSpans = data.get(i1).getRowSpan().split(",");;
                                if (rowSpans.length > 0) {
                                    //垂直合并单元格
                                    mergeCellsVertically(table, Integer.parseInt(rowSpans[0]), Integer.parseInt(rowSpans[1]), Integer.parseInt(rowSpans[2]));
                                }
                            }
                        }
                        //填充表格内容
                        for (int i1 = 0; i1 < data.size(); i1++) {
                            List<String[]> values = data.get(i1).getValues();
                            for (int i2 = 0; i2 < values.size(); i2++) {
                                for (int i3 = 0; i3 < values.get(i2).length; i3++) {
                                    XWPFTableCell cell = table.getRow(i1).getCell(i3);
                                    CTTc ctTc = cell.getCTTc();
                                    CTP ctP = (ctTc.sizeOfPArray() == 0) ? ctTc.addNewP() : ctTc.getPArray(0);
                                    XWPFParagraph par = cell.getParagraph(ctP);
                                    //设置水平居中
                                    par.setAlignment(ParagraphAlignment.CENTER);
                                    //设置垂直居中
                                    par.setVerticalAlignment(TextAlignment.CENTER);
                                    CTTcPr tcpr = ctTc.addNewTcPr();
                                    CTTblWidth cellw = tcpr.addNewTcW();
                                    cellw.setType(STTblWidth.DXA);
                                    int floor = (int) Math.floor(8000 / values.size());
                                    cellw.setW(new BigInteger(String.valueOf(floor)));
                                    String value = values.get(i2)[i3];
                                    cell.setText(value);
                                    //单元格插入图片使用
                                    //setCellImage(cell,"jpg",null);
                                }
                            }
                        }
                    }
                    if ("02".equals(type)) {
                        //添加第一个段落
                        XWPFParagraph paragraph = document.createParagraph();
                        //设置之段落左对齐
                        paragraph.setAlignment(ParagraphAlignment.valueOf(STJc.INT_LEFT));
                        // ---------以上是设置整段的,以下为设置内容
                        XWPFRun firstRun = paragraph.createRun();
                        firstRun.setFontSize(12);
                        firstRun.setFontFamily("宋体");
                        for (int i1 = 1; i1 < isHierarchy; i1++) {
                            firstRun.addTab();
                        }
                        firstRun.setText(text);
                    }
                    if ("03".equals(type)) {

                    }
                }
            }
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode("指导卡.docx", "UTF-8"));
            //创建一个输出流
            outputStream = response.getOutputStream();
            document.write(outputStream);
        } catch (Exception e) {
            GlobalLogger.error("导出出现问题请排查:", e);
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }


    /**
     * @Description: 跨列合并  水平合并单元格
     * table要合并单元格的表格
     * row 要合并哪一行的单元格  合并哪一行
     * fromCell开始合并的单元格  合并的起点单元格
     * toCell合并到哪一个单元格  合并的终点单元格
     */
    public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
        for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            if (cellIndex == fromCell) {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
     * @Description: 跨行合并  垂直合并单元格
     * table要合并单元格的表格
     * col要合并哪一列的单元格
     * fromRow从哪一行开始合并单元格
     * toRow合并到哪一个行
     */
    public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            if (rowIndex == fromRow) {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    //单元格写入图片
    private static void setCellImage(XWPFTableCell cell, String type, InputStream is) throws Exception {
        List<XWPFParagraph> paragraphs = cell.getParagraphs();
        XWPFParagraph newPara = paragraphs.get(0);
        XWPFRun imageCellRunn = newPara.createRun();
        int format = 0;
        if (type.endsWith("jpeg") || type.endsWith("jpg")) {
            format = XWPFDocument.PICTURE_TYPE_JPEG;
        } else {
            format = XWPFDocument.PICTURE_TYPE_PNG;
        }
        imageCellRunn.addPicture(is, format, "图片名称", Units.toEMU(100), Units.toEMU(100)); // 200x200 pixels
    }
}

参数如下:

{
    "tableName": "标题",
    "directory": [
        {
            "isHierarchy": "1",
            "type": "02",
            "text": "一级标题"
        },
        {
            "isHierarchy": "2",
            "type": "02",
            "text": "二级标题"
        },
        {
            "isHierarchy": "3",
            "type": "02",
            "text": "三级标题"
        },
        {
            "isHierarchy": "0",
            "type": "02",
            "text": "如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。 如果不想终止,则必须捕获所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。"
        },
        {
            
            "type": "01",
            "data": [
                {
                    "values": [
                        [
                            "序号",
                            "序号",
                            "名称"
                        ]
                    ]
                },
                {
                    "values": [
                        [
                            "01",
                            "01",
                            "张三"
                        ]
                    ]
                },
                {
                    "values": [
                        [
                            "01",
                            "01",
                            "李四"
                        ]
                    ],
                    "colSpan":"1,0,1"
                },
                {
                    "values": [
                        [
                            "01",
                            "01",
                            "王五四"
                        ]
                    ],
                    "rowSpan":"2,2,3"
                }
                
            ]
        }
    ]
}

效果图如下:
动态导出word,util,utils,word
本demo仅用于学习使用,可根据具体业务对代码进行适当整改使用。
不足之处,请留言以便完善整改。文章来源地址https://www.toymoban.com/news/detail-695306.html

到了这里,关于动态导出word的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 常用函数utils

    结束Windows进程 释放端口 启动Windows进程

    2024年02月07日
    浏览(24)
  • SpringBoot动态导出word文档(完美实整教程 复制即可使用,不能实现你找我)

    最近有一个需求是需要动态导出合同、订单等信息,导出一个word文档供客户进行下载查看。 需要导出的word文件,主要可以分为两种类型。 导出固定内容和图片的word文档 导出表格内容不固定的word文档 经过对比工具,我实践过两种实现方式。第一种是FreeMarker模板来进行填充

    2024年02月03日
    浏览(38)
  • 解决java.util.NoSuchElementException

    博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客👦🏻 《java 面试题大全》 🍩惟余辈才疏学浅,临摹之作或有不妥之处,还请读者海涵指正。☕🍭 《MYSQL从入门到精通》数据库是开发者必会基础之一~ 🪁 吾期望此文有资助于尔,即使粗浅难及深广,亦备添少许微薄

    2024年02月05日
    浏览(61)
  • Util应用框架基础(四) - 验证

    本节介绍Util应用框架如何进行验证. 验证是业务健壮性的基础. .Net 提供了一套称为 DataAnnotations 数据注解的方法,可以对属性进行一些基本验证,比如必填项验证,长度验证等. Util应用框架使用标准的数据注解作为基础验证,并对自定义验证进行扩展. Nuget包名: Util.Validation . 通常不

    2024年02月05日
    浏览(53)
  • 用Promise实现util函数

    有些时候,我们需要依赖于异步的返回结果做一些后续处理, until 函数在这种场景下非常有用,你能实现它吗 ? 让我们来试试吧 👇:

    2024年01月16日
    浏览(22)
  • Python的utils库介绍

    目录 1. 引言 2. Python的常用utils库 2.1. ​​os​​模块 2.2. ​​datetime​​模块 2.3. ​​random​​模块 2.4. ​​json​​模块 2.5. ​​logging​​模块 2.6. ​​argparse​​模块 2.7. ​​requests​​库 3. 结论 Python的utils库介绍 在Python编程中,utils库是一个非常实用的工具集,它提供了

    2024年02月03日
    浏览(22)
  • Util应用框架 7.x 来了

    Util是一个.Net平台下的应用框架,旨在提升中小团队的开发能力,由工具类、分层架构基类、Ui组件,配套代码生成模板,权限等组成。 Util应用框架的最新版本是7.x,保持与.Net最新稳定版本同步更新。 与Util 1.x相比,最新版本代码经过完全重写,提升了模块化程度,抛弃了一些历

    2024年02月08日
    浏览(81)
  • Utilities非默认目录构建和安装

    在AppArmor零知识学习八、源码构建(5)中,详细介绍了Utilities的构建步骤,但那完全使用的是官网给出的默认参数。如果需要将目标文件生成到指定目录而非默认的/usr,则需要进行一些修改,本文就来详述如何进行修改。 必须说明以下两点: (1)Utilities的构建必须在前述步

    2023年04月21日
    浏览(19)
  • Util 应用框架 UI 全新升级

    Util UI 已经开发多年, 并在多家公司的项目使用. 不过一直以来, Util UI 存在一些缺陷, 始终未能解决. 最近几个月, Util 团队下定决心, 终于彻底解决了所有已知缺陷. Util 应用框架 UI 建立在 Angular , Ng-Zorro, Ng-Alain 基础之上, 用于开发企业中后台. 简洁 Util UI 通常可以将复杂组件的

    2024年04月28日
    浏览(36)
  • 如何解决java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@7566d7cf r...

    Java中的 java.util.concurrent.RejectedExecutionException 异常表示无法将任务提交到线程池中执行。这通常是因为线程池处于关闭状态或者已经达到了最大线程数,无法再接受新的任务。 要解决这个异常,你可以考虑以下几种方法: 检查线程池的状态,确保它处于可以接受新任务的状态

    2024年02月13日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包