postman json格式文档转word表格文档

postman json格式文档转word表格文档

说明

json版本Collection v2.1,运行main方法输入json文件路径,生成word
参考:
https://gitee.com/zhexiao/postman-to-word (解析思路).
https://blog.csdn.net/qq_26408545/article/details/110669104 (poi导出操作).
https://www.cnblogs.com/sun-flower1314/p/10128796.html (poi导出操作).
https://tool.oschina.net/apidocs/apidoc?api=apache-POI (api文档).

遇到的问题
单元格文字过长,表格样式会变, 有擅长导出的大佬还请指点一下。

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>JsonToWord</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--office解析需要的包-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.61</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

代码

package com.jsonToWord;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;


/**
 * @author zxq
 * @date 2020-09-15 22:17
 * @description 解析postman Collection v2.1版本的json文件到word中
 *
 *              参考:https://gitee.com/zhexiao/postman-to-word (解析思路),
 *                   https://blog.csdn.net/qq_26408545/article/details/110669104 (poi导出操作),
 *                   https://www.cnblogs.com/sun-flower1314/p/10128796.html (poi导出操作),
 *                   https://tool.oschina.net/apidocs/apidoc?api=apache-POI (api文档)
 *
 */
public class JsonToWord {

    private static final Logger log = LoggerFactory.getLogger(com.jsonToWord.JsonToWord.class);


    public static void main(String[] args) {
        try {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入json文件路径:");
            //读取字符串型输入
            String jsonFile = sc.nextLine();
            File file = new File(jsonFile);
            if (!file.exists()) {
                System.out.println("找不到文件");
                System.out.println("程序结束!");
            }
            System.out.println(jsonFile);
            String wordFile = jsonFile.substring(0,jsonFile.lastIndexOf("\\") + 1);
            if (!file.exists()) {
                file.mkdir();
            }
            FileInputStream fileInputStream = new FileInputStream(file);
            String res = read(fileInputStream);
            JSONObject jsonObject = JSON.parseObject(res);
            XWPFDocument word = createWordFile(jsonObject);
            String fileUrl = wordFile + System.currentTimeMillis() + "word.docx";
            saveDocument(word,fileUrl);
            System.out.println("word导出完成:" + fileUrl);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置文档标题
     * @param jsonObject
     * @return
     */
    private static XWPFDocument createWordFile(JSONObject jsonObject) {
        //解析json,将json中的数据放到word中
        //获取api文档名称
        JSONObject info = (JSONObject) jsonObject.get("info");
        String title = (String)info.get("name");
        XWPFDocument document = new XWPFDocument();

        //设置标题
        createTitleParagraph(document,title);

        JSONArray items = (JSONArray)jsonObject.get("item");
        for(Object itemObj:items){
            JSONObject item = (JSONObject)itemObj;
            //设置接口文件表格内容
            createTable(item,document);
        }


        return  document;

    }

    /**
     * 生成接口表格
     * @param item
     * @param document
     */
    private static void createTable(JSONObject item, XWPFDocument document) {

        //创建1*6的表格
        int row = 0;
        //接口名
        XWPFTable table = document.createTable(1, 6);
        //设置表格宽度固定,但是有过长的字段时会失效
        CTTblPr ctTblPr = table.getCTTbl().addNewTblPr();
        CTTblLayoutType ctTblLayoutType = ctTblPr.isSetTblLayout()?ctTblPr.getTblLayout():ctTblPr.addNewTblLayout();
        ctTblLayoutType.setType(STTblLayoutType.FIXED);
        //设置表格样式
        //table.setWidth(7800);
        XWPFTableCell cell1 = table.getRow(row).getCell(0);
        //设置表格宽度
        cell1.setWidth("1300");
        cell1.addParagraph().createRun().setText("接口名称");
        XWPFTableCell cell2 = table.getRow(row).getCell(1);
        //合并2-6单元格
        mergeCellH(table,cell2,row,1,5);
        cell2.setWidth("6500");
        cell2.addParagraph().createRun().setText((String)item.get("name"));
        row++;
        //请求方法
        table.createRow();
        XWPFTableCell cell3 = table.getRow(row).getCell(0);
        cell3.setWidth("1300");
        cell3.addParagraph().createRun().setText("接口方法");
        XWPFTableCell cell4 = table.getRow(row).getCell(1);
        //合并2-6单元格
        mergeCellH(table,cell4,row,1,5);
        cell4.setWidth("6500");
        cell4.addParagraph().createRun().setText((String)((JSONObject)item.get("request")).get("method"));
        row++;
        //地址
        table.createRow();
        XWPFTableCell cell5 = table.getRow(row).getCell(0);
        cell5.setWidth("1300");
        cell5.addParagraph().createRun().setText("接口地址");
        XWPFTableCell cell6 = table.getRow(row).getCell(1);
        //合并2-6单元格
        mergeCellH(table,cell6,row,1,5);
        String url = (String) ((JSONObject) ((JSONObject) item.get("request")).get("url")).get("raw");
        if(url.contains("?")){
            url = url.substring(0, url.indexOf("?"));
        }
        cell6.setWidth("6500");
        cell6.addParagraph().createRun().setText(url);
        row++;
        //请求头
        //设置请求头标题
        int headStart = row;
        int headEnd = row;
        table.createRow();
        XWPFTableCell cell7 = table.getRow(row).getCell(0);
        cell7.setWidth("1300");
        XWPFTableCell cell8 = table.getRow(row).getCell(1);
        cell8.setWidth("1300");
        cell8.addParagraph().createRun().setText("参数名");
        XWPFTableCell cell9 = table.getRow(row).getCell(2);
        cell9.setWidth("1300");
        cell9.addParagraph().createRun().setText("类型");
        XWPFTableCell cell10 = table.getRow(row).getCell(3);
        mergeCellH(table,cell10,row,3,5);
        cell10.setWidth("3900");
        XWPFRun run = cell10.addParagraph().createRun();
        run.setText("举例");
        row++;
        //请求头参数
        JSONArray headers = (JSONArray)((JSONObject)item.get("request")).get("header");
        if(headers.size() == 0){
            //没有请求头参数给个空行
            table.createRow();
            XWPFTableCell cell11 = table.getRow(row).getCell(0);
            cell11.setWidth("1300");
            XWPFTableCell cell12 = table.getRow(row).getCell(1);
            cell12.setWidth("1300");
            XWPFTableCell cell13 = table.getRow(row).getCell(2);
            cell13.setWidth("1300");
            XWPFTableCell cell14 = table.getRow(row).getCell(3);
            mergeCellH(table,cell14,row,3,5);
            cell14.setWidth("3900");
            headEnd = row;
            row++;
        }else{
            //有数据循环添加到表格
            for(Object headerObj:headers){
                JSONObject header = (JSONObject)headerObj;
                table.createRow();
                setHeader(header,table,row);
                headEnd = row;
                row++;
            }
        }
        //合并请求头列
        mergeCellV(table,cell7,0,headStart,headEnd);
        cell7.addParagraph().createRun().setText("请求头");

        //入参
        //设置入参标题
        int paramStart = row;
        int paramEnd = row;
        table.createRow();
        XWPFTableCell cell15 = table.getRow(row).getCell(0);
        cell15.addParagraph().createRun().setText("");
        XWPFTableCell cell16 = table.getRow(row).getCell(1);
        cell16.setWidth("1300");
        cell16.addParagraph().createRun().setText("参数名");
        XWPFTableCell cell17 = table.getRow(row).getCell(2);
        cell17.setWidth("1300");
        cell17.addParagraph().createRun().setText("类型");
        XWPFTableCell cell18 = table.getRow(row).getCell(3);
        cell18.setWidth("1300");
        cell18.addParagraph().createRun().setText("必填");
        XWPFTableCell cell19 = table.getRow(row).getCell(4);
        cell19.setWidth("1300");
        cell19.addParagraph().createRun().setText("举例");
        XWPFTableCell cell20 = table.getRow(row).getCell(5);
        cell20.setWidth("1300");
        cell20.addParagraph().createRun().setText("描述");
        row++;
        //设置具体参数
        JSONArray querys = (JSONArray)((JSONObject)((JSONObject)item.get("request")).get("url")).get("query");
        if(querys != null && querys.size() != 0){
            //有数据循环添加到表格
            for(Object queryObj :querys){
                JSONObject query = (JSONObject) queryObj;
                table.createRow();
                setParam(query,table,row);
                paramEnd = row;
                row++;
            }
        }else{
            //为空或没有参数,设置一个空行
            table.createRow();
            setParamStytle(table,row);
            paramEnd = row;
            row++;
        }
        //合并参数列
        mergeCellV(table,cell15,0,paramStart,paramEnd);
        cell15.setWidth("1300");
        cell15.addParagraph().createRun().setText("请求参数");
        //返回值
        table.createRow();
        JSONArray responses = (JSONArray) item.get("response");
        if(responses != null && responses.size() > 0){
            XWPFTableCell cell21 = table.getRow(row).getCell(0);
            //设置表格宽度
            cell21.setWidth("1300");
            cell21.addParagraph().createRun().setText("返回值");
            XWPFTableCell cell22 = table.getRow(row).getCell(1);
            //合并2-6单元格
            mergeCellH(table,cell22,row,1,5);

            for(Object responseObj : responses){
                JSONObject response = (JSONObject)responseObj;
                cell22.addParagraph().createRun().setText((String)response.get("body"));
            }
            cell22.setWidth("6500");
            row++;
        }else{
            XWPFTableCell cell21 = table.getRow(row).getCell(0);
            //设置表格宽度
            cell21.setWidth("1300");
            cell21.addParagraph().createRun().setText("返回值");
            XWPFTableCell cell22 = table.getRow(row).getCell(1);
            //合并2-6单元格
            mergeCellH(table,cell22,row,1,5);
            cell22.setWidth("6500");
            row++;
        }
        //防止表格挨在一起影响阅读
        document.createParagraph();


    }

    /**
     * 设置接口参数
     * @param query
     * @param table
     * @param row
     */
    private static void setParam(JSONObject query, XWPFTable table, int row) {
        XWPFTableCell cell0 = table.getRow(row).getCell(0);
        cell0.setWidth("1300");
        XWPFTableCell cell1 = table.getRow(row).getCell(1);
        cell1.setWidth("1300");
        cell1.addParagraph().createRun().setText((String)query.get("key"));
        XWPFTableCell cell2 = table.getRow(row).getCell(2);
        cell2.setWidth("1300");
        XWPFTableCell cell3 = table.getRow(row).getCell(3);
        cell3.setWidth("1300");
        XWPFTableCell cell4 = table.getRow(row).getCell(4);
        cell4.setWidth("1300");
        cell4.addParagraph().createRun().setText((String)query.get("value"));
        XWPFTableCell cell5 = table.getRow(row).getCell(5);
        cell5.setWidth("1300");
        cell5.addParagraph().createRun().setText((String)query.get("description"));
    }

    private static void setParamStytle(XWPFTable table, int row) {
        XWPFTableCell cell0 = table.getRow(row).getCell(0);
        cell0.setWidth("1300");
        XWPFTableCell cell1 = table.getRow(row).getCell(1);
        cell1.setWidth("1300");
        XWPFTableCell cell2 = table.getRow(row).getCell(2);
        cell2.setWidth("1300");
        XWPFTableCell cell3 = table.getRow(row).getCell(3);
        cell3.setWidth("1300");
        XWPFTableCell cell4 = table.getRow(row).getCell(4);
        cell4.setWidth("1300");
        XWPFTableCell cell5 = table.getRow(row).getCell(5);
        cell5.setWidth("1300");
    }

    /**
     * 设置请求头
     * @param header
     * @param table
     * @param row
     */
    private static void setHeader(JSONObject header, XWPFTable table, int row) {
        XWPFTableCell cell0 = table.getRow(row).getCell(0);
        cell0.setWidth("1300");
        XWPFTableCell cell1 = table.getRow(row).getCell(1);
        cell1.setWidth("1300");
        cell1.addParagraph().createRun().setText((String)header.get("key"));
        XWPFTableCell cell2 = table.getRow(row).getCell(2);
        cell2.setWidth("1300");
        cell2.addParagraph().createRun().setText((String)header.get("type"));
        XWPFTableCell cell3 = table.getRow(row).getCell(3);
        mergeCellH(table,cell3,row,3,5);
        cell3.setWidth("3900");
        XWPFRun run = cell3.addParagraph().createRun();
        run.setText((String)header.get("value"));

    }

    /**
     * 合并列
     * @param table:表格对象
     * @param cell:合并起始单元格对象
     * @param row:行数
     * @param start:合并起始列
     * @param end:合并结束列
     */
    private static void mergeCellH(XWPFTable table, XWPFTableCell cell, int row, int start, int end) {
        cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
        for (int i = start + 1; i <= end; i++) {
            XWPFTableCell cellNext = table.getRow(row).getCell(i);
            cellNext.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
        }
    }

    /**
     * 合并行
     * @param table:表格对象
     * @param cell:合并起始单元格对象
     * @param col:列数
     * @param start:合并起始行
     * @param end:合并结束行
     */
    private static void mergeCellV(XWPFTable table, XWPFTableCell cell, int col, int start, int end) {
        cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
        for (int i = start + 1; i <= end; i++) {
            XWPFTableCell cellNext = table.getRow(i).getCell(col);
            cellNext.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
        }
    }

    /**
     * 导出word
     * @param document
     * @param savePath
     * @throws IOException
     */
    public static void saveDocument(XWPFDocument document, String savePath) throws IOException {
        File file = new File(savePath);
        OutputStream os = new FileOutputStream(file);
        document.write(os);
        os.close();
    }

    /**
     * word标题
     * @param document
     * @param title
     */
    public static void createTitleParagraph(XWPFDocument document,String title) {
        //新建一个标题段落对象(就是一段文字)
        XWPFParagraph titleParagraph = document.createParagraph();
        //样式居中
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        //创建文本对象
        XWPFRun titleFun = titleParagraph.createRun();
        //设置标题的名字
        titleFun.setText(title);
        //加粗
        titleFun.setBold(true);
        //设置颜色
        titleFun.setColor("000000");
        //字体大小
        titleFun.setFontSize(25);
        //换行
        titleFun.addBreak();
    }



    /**
     * 读取文件
     * 使用 Charset + CharsetDecoder 解决了中文乱码问题
     *
     * @param fis
     * @return
     */
    public static String read(FileInputStream fis) {
        StringBuilder stringBuilder = new StringBuilder();

        //解决中文乱码问题
        Charset charset = StandardCharsets.UTF_8;
        CharsetDecoder decoder = charset.newDecoder();
        char[] charCache = null;

        try{
            FileChannel fisChannel = fis.getChannel();
            //分配缓冲区、分配字符缓冲区解决中文乱码
            ByteBuffer byteBuffer = ByteBuffer.allocate(10240);
            CharBuffer charBuffer = CharBuffer.allocate(10240);

            //读取数据
            while (fisChannel.read(byteBuffer) != -1) {
                //上面把数据写入到了buffer,所以可知上面的buffer是写模式,调用flip把buffer切换到读模式,读取数据
                byteBuffer.flip();

                //把字节buffer解码到字符buffer
                decoder.decode(byteBuffer, charBuffer, true);

                //字符buffer切换到读模式
                charBuffer.flip();

                //存储字符
                charCache = new char[charBuffer.length()];
                while (charBuffer.hasRemaining()) {
                    charBuffer.get(charCache);
                }
                stringBuilder.append(charCache);

                //读完了buffer,清空buffer
                charBuffer.clear();
                byteBuffer.clear();
            }
        } catch (Exception e) {
            log.info("读取文件异常,e={}", e.getMessage());
            return null;
        }

        return stringBuilder.toString();
    }
}

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值