导出数据库表结构到文档中

4 篇文章 0 订阅
4 篇文章 0 订阅

导出效果:

完整代码:

Controller层:

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Api(value = "TestController",description="TestController")
@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private IMetadataService metadataService;

    @IgnoreSecurity
    @ApiOperation(value = "DDL2WordTable")
    @GetMapping(value = "/DDL2WordTable")
    public void DDL2WordTable(HttpServletRequest request, HttpServletResponse response){
        try {
            this.metadataService.DDL2WordTable( response );
        }catch ( Exception e ){
            e.printStackTrace();
        }
    }
}

service 层:

IMetadataService.java:
import javax.servlet.http.HttpServletResponse;
import java.util.List;

public interface IMetadataService {
    void DDL2WordTable(HttpServletResponse response);

    List<MySqlTableInfo> collectTableInfos();
}
MetadataServiceImpl.java:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class MetadataServiceImpl implements IMetadataService {

    @Autowired
    private MetadataMapper metadataMapper;

    @Value( "${spring.datasource.url}" )
    private String url;

    @Override
    public void DDL2WordTable(HttpServletResponse response) {
        try {
            List<MySqlTableInfo> tableInfos = this.collectTableInfos();
            if( tableInfos == null || tableInfos.size() == 0 ){
                return;
            }
            for( MySqlTableInfo tableInfo:tableInfos ){
                System.out.println( tableInfo.getTableName() + "  " + tableInfo.getFieldInfos().size() );
            }
            response.setContentType("application/msword");
            String filename = URLEncoder.encode( "xxxx数据库表结构.docx","UTF-8" );
            response.setHeader("Content-Disposition", "attachment; filename=" + filename);
            POIWordUtils.writeMysqlTables2Word( tableInfos,response.getOutputStream() );
        }catch ( Exception e ){
            e.printStackTrace();
        }
    }

    @Override
    public List<MySqlTableInfo> collectTableInfos() {
        List<String> tableNames = this.metadataMapper.showTableNames();
        if( tableNames == null || tableNames.size() == 0 ){
            return null;
        }
        // todo 从 jdbc url 中提取???
        String databaseName = "xxxxxxxxxxxxxx";
        List<MySqlTableInfo> tableInfos = new ArrayList<>();
        for( String tableName:tableNames ){
            List<InformationSchemaCOLUMNS> columnsList = this.metadataMapper.queryInformationSchemaCOLUMNS( databaseName,tableName );
            if( columnsList == null || columnsList.size() == 0 ){
                continue;
            }
            MySqlTableInfo tableInfo = new MySqlTableInfo();
            List<MySqlTableFieldInfo> fieldInfos = new ArrayList<>();
            for( InformationSchemaCOLUMNS columns:columnsList ){
                MySqlTableFieldInfo fieldInfo = new MySqlTableFieldInfo();
                fieldInfo.setName( columns.getColumnName() );
                fieldInfo.setType( columns.getDataType() );
                Long character_maximum_length = columns.getCharacterMaximumLength();
                if( character_maximum_length != null ){
                    fieldInfo.setLength( character_maximum_length.toString() );
                }
                String is_nullable = columns.getIsNullable();
                if( "YES".equals( is_nullable ) ){
                    fieldInfo.setNullable( true );
                }else if( "NO".equals( is_nullable ) ){
                    fieldInfo.setNullable( false );
                }
                fieldInfo.setComment( columns.getColumnComment() );
                String column_key = columns.getColumnKey();
                if( "PRI".equals( column_key ) ){
                    fieldInfo.setPrimaryKey( true );
                }else if( "UNI".equals( column_key ) ){
                    // todo 唯一索引
                    fieldInfo.setIndexType( "唯一索引" );
                }else if( "MUL".equals( column_key ) ){
                    fieldInfo.setIndexType( "普通索引" );
                }else {
                    // todo 其他索引返回什么
                }
                fieldInfo.setDefaultValue( columns.getColumnDefault() );
                fieldInfos.add( fieldInfo );
            }
            tableInfo.setTableName( tableName );
            tableInfo.setFieldInfos( fieldInfos );
            tableInfos.add( tableInfo );
        }

        // set titles
        List<String> titles = new ArrayList<>();
        titles.add( "字段名称" );
        titles.add( "类型" );
        titles.add( "长度" );
        titles.add( "允许为空" );
        titles.add( "字段说明" );
        titles.add( "键" );
        titles.add( "默认值" );
        titles.add( "索引类型" );
        for( MySqlTableInfo tableInfo:tableInfos ){
            tableInfo.setTitles( titles );
        }
        return tableInfos;
    }
}

Mapper 层:

MetadataMapper.java:
import org.apache.ibatis.annotations.Param;

import java.util.List;

@DataSource("dataSource")
public interface MetadataMapper extends BaseMapper {
    List<String> showTableNames();

    List<InformationSchemaCOLUMNS> queryInformationSchemaCOLUMNS(@Param( "databaseName" ) String databaseName,
                                                                 @Param( "tableName" ) String tableName);
}
MetadataMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xxx.mapper.MetadataMapper">

    <select id="showTableNames" resultType="java.lang.String">
        SHOW TABLES
    </select>

    <select id="queryInformationSchemaCOLUMNS" resultType="com.xxx.vo.InformationSchemaCOLUMNS">
        SELECT
            TABLE_CATALOG AS tableCatalog,
            TABLE_SCHEMA tableSchema,
            TABLE_NAME AS tableName,
            COLUMN_NAME AS columnName,
            ORDINAL_POSITION AS ordinalPosition,
            COLUMN_DEFAULT AS columnDefault,
            IS_NULLABLE AS isNullable,
            DATA_TYPE AS dataType,
            CHARACTER_MAXIMUM_LENGTH AS characterMaximumLength,
            CHARACTER_OCTET_LENGTH AS characterOctetLength,
            NUMERIC_PRECISION AS numericPrecision,
            NUMERIC_SCALE AS numericScale,
            DATETIME_PRECISION AS datetimePrecision,
            CHARACTER_SET_NAME AS characterSetName,
            COLLATION_NAME AS collationName,
            COLUMN_TYPE AS columnType,
            COLUMN_KEY AS columnKey,
            EXTRA AS extra,
            PRIVILEGES AS privileges,
            COLUMN_COMMENT AS columnComment,
            GENERATION_EXPRESSION AS generationExpression
        FROM
            information_schema.COLUMNS
        WHERE
            table_name = #{tableName}
        AND
            table_schema = #{databaseName}
    </select>
</mapper>
用到的 VO 类:

InformationSchemaCOLUMNS.java:
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class InformationSchemaCOLUMNS {

    private Long ordinalPosition;

    /**
     * 字段长度
     */
    private Long characterMaximumLength;
    private Long characterOctetLength;
    private Long numericPrecision;
    private Long numericScale;
    private Long datetimePrecision;
    private String tableCatalog;
    private String tableSchema;
    private String tableName;

    /**
     * 字段名称,如:username
     */
    private String columnName;

    /**
     * 默认值
     */
    private String columnDefault;

    /**
     * 字段是否允许空值,'YES'、'NO'
     */
    private String isNullable;

    /**
     * 字段的数据类型,如:varchar、datetime ...
     */
    private String dataType;
    private String characterSetName;
    private String collationName;
    private String columnType;

    /**
     * 该字段的索引类型( 'PRI':主键索引,'UNI':唯一索引,'MUL':普通索引 )
     */
    private String columnKey;
    private String extra;
    private String privileges;

    /**
     * 字段的注释
     */
    private String columnComment;
    private String generationExpression;
}
MySqlTableInfo.java:
import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Getter
@Setter
public class MySqlTableInfo {

    private String tableName;

    private List<String> titles;
    private List<MySqlTableFieldInfo> fieldInfos;
}
MySqlTableFieldInfo.java:
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class MySqlTableFieldInfo {

    /**
     * 字段名称,如:username
     */
    private String name;

    /**
     * 字段的数据类型
     */
    private String type;

    /**
     * 字段长度
     */
    private String length;

    /**
     * 字段是否允许空值
     */
    private boolean nullable;

    /**
     * 字段的注释
     */
    private String comment;

    /**
     * 该字段是否是主键
     */
    private boolean primaryKey;

    /**
     * 默认值
     */
    private String defaultValue;
    private String indexType;
}
POI 工具类:

POIWordUtils.java:
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

public class POIWordUtils {

    public static void writeMysqlTables2Word(List<MySqlTableInfo> tableInfos, OutputStream outputStream){
        XWPFDocument xwpfDocument = null;
        try {
            xwpfDocument = new XWPFDocument();
            // 创建1行3列的表格

            for( MySqlTableInfo tableInfo:tableInfos ){
                appendMysqlTable2Word( xwpfDocument,tableInfo );
            }
            xwpfDocument.write( outputStream );
        }catch ( Exception e ){
            e.printStackTrace();
        }finally {
            if( xwpfDocument != null ){
                try {
                    xwpfDocument.close();
                }catch ( Exception e ){
                    e.printStackTrace();
                }
            }
        }
    }

    private static void appendMysqlTable2Word(XWPFDocument xwpfDocument, MySqlTableInfo tableInfo) {
        xwpfDocument.createParagraph().createRun().setText( "" );
        xwpfDocument.createParagraph().createRun().setText( "" );
        xwpfDocument.createParagraph().createRun().setText( "" );
        XWPFRun run = xwpfDocument.createParagraph().createRun();
        run.setFontSize( 12 );
        run.setText( tableInfo.getTableName() );

        List<String> titles = tableInfo.getTitles();
        List<MySqlTableFieldInfo> fieldInfos = tableInfo.getFieldInfos();
        int colCount = titles.size();
        int rowCount = 1 + tableInfo.getFieldInfos().size();

        XWPFTable table = xwpfDocument.createTable(rowCount,colCount );
        table.setWidth(10000);
        // table.setTableAlignment( TableRowAlign.CENTER );
        XWPFTableRow row_title = table.getRow(0);

        // 设置标题行
        for( int colIndex = 0;colIndex<colCount;colIndex++ ){
            XWPFTableCell cell = row_title.getCell(colIndex);
            cell.setWidthType( TableWidthType.PCT );
            cell.setWidth( "12.5%" );
            String title = titles.get(colIndex);
            setTextForCell( cell,title );
            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        }
        for( int rowIndex=1;rowIndex<rowCount;rowIndex++ ){
            XWPFTableRow row = table.getRow(rowIndex);
            row.setHeight( 500 );
            MySqlTableFieldInfo fieldInfo = fieldInfos.get(rowIndex - 1);

            XWPFTableCell cell0 = row.getCell(0);
            XWPFTableCell cell1 = row.getCell(1);
            XWPFTableCell cell2 = row.getCell(2);
            XWPFTableCell cell3 = row.getCell(3);
            XWPFTableCell cell4 = row.getCell(4);
            XWPFTableCell cell5 = row.getCell(5);
            XWPFTableCell cell6 = row.getCell(6);
            XWPFTableCell cell7 = row.getCell(7);

            cell0.setWidthType( TableWidthType.PCT );
            cell1.setWidthType( TableWidthType.PCT );
            cell2.setWidthType( TableWidthType.PCT );
            cell3.setWidthType( TableWidthType.PCT );
            cell4.setWidthType( TableWidthType.PCT );
            cell5.setWidthType( TableWidthType.PCT );
            cell6.setWidthType( TableWidthType.PCT );
            cell7.setWidthType( TableWidthType.PCT );

           /* cell0.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            cell1.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            cell2.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            cell3.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            cell4.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            cell5.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            cell6.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            cell7.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);*/

            cell0.setWidth( "12.5%" );
            cell1.setWidth( "12.5%" );
            cell2.setWidth( "12.5%" );
            cell3.setWidth( "12.5%" );
            cell4.setWidth( "12.5%" );
            cell5.setWidth( "12.5%" );
            cell6.setWidth( "12.5%" );
            cell7.setWidth( "12.5%" );

            setTextForCell( cell0,fieldInfo.getName() );
            setTextForCell( cell1,fieldInfo.getType() );
            String length = fieldInfo.getLength();
            if( length == null ){
                setTextForCell( cell2,"" );
            }else {
                setTextForCell( cell2,String.valueOf( fieldInfo.getLength() ) );
            }
            if( fieldInfo.isNullable() ){
                setTextForCell( cell3,"YES" );
            }else {
                setTextForCell( cell3,"NO" );
            }
            setTextForCell( cell4,fieldInfo.getComment() );
            if( fieldInfo.isPrimaryKey() ){
                setTextForCell( cell5,"主键" );
            }
            setTextForCell( cell6,fieldInfo.getDefaultValue() );
            setTextForCell( cell7,fieldInfo.getIndexType() );
        }
    }

    private static void setTextForCell(XWPFTableCell cell,String text) {
        // cell.setText( text );
        CTTc ctTc = cell.getCTTc();
        CTP ctP = (ctTc.sizeOfPArray() == 0) ?ctTc.addNewP() : ctTc.getPArray(0);
        XWPFParagraph paragraph = cell.getParagraph(ctP);
        XWPFRun run = paragraph.createRun();
         paragraph.setAlignment( ParagraphAlignment.CENTER );
         paragraph.setVerticalAlignment( TextAlignment.CENTER );
        // 即小四
        run.setFontSize( 12 );
        run.setText( text );
    }
}

/***********************基本描述**********************************/ 0、根据可以单独生成javaBean后缀可以自定义 1、工具本身是非常简单的,每个人都能做就是使用模板替换生成相应文件 2、工具主要针对SpringMvc+Mybatis注解+Mysql生成对象,dao、sqlDao、interface、实现接口 3、根据生成Excel 4、生成成功后倒入到自己对应的项目,然后Ctrl+Shipt+O(Eclipse快速倒入包)实现 5、里面因为运用的是注解,所以很多包我就没有提供了因为这些都是很基础的东西,不会的同学可以去网上查看搭建Mybatis的注解 6、生成了些什么,具体主要是对单的增、删、改、查(分页) /********************************/ /********************************/ /*************完全免费***********/ /********************************/ /********************************/ 如果大家喜欢可以再给我提其他功能,有时间我加上 /*********************************************************************************/ 模板介绍: MySql.Data.dll :连接Mysql基本dl我们的的驱动。 foxjava.exe :直接运行程序 xml : Excel文件夹 ##### TemplateXml.xml 根据数据库对应生成字段描述,生成后最好用WPS打开,然后重新另存为office认识的Excel template : 文件生成模板(非常重要的不能修改) ##### BasePojo.template 所有基础对象都要继承,方便序列化(系统自动生成) ##### Pager.template 分页对象 (系统自动生成) ##### dao.template 数据库接口Dao(mybatis接口方式,在方法上写sql,复杂的使用sqlProvider) ##### daoSqlProvider.template 复杂sql提供者 ##### service.template 对外开放的接口 ##### serviceImpl.template 实现开放接口,基本数据操作逻辑 /*********************************************************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值