🎉 Initial commit
This commit is contained in:
106
.gitignore
vendored
106
.gitignore
vendored
@@ -1,106 +0,0 @@
|
|||||||
# ---> Go
|
|
||||||
# If you prefer the allow list template instead of the deny list, see community template:
|
|
||||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
|
||||||
#
|
|
||||||
# Binaries for programs and plugins
|
|
||||||
*.exe
|
|
||||||
*.exe~
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
|
||||||
*.test
|
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
|
||||||
*.out
|
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
|
||||||
# vendor/
|
|
||||||
|
|
||||||
# Go workspace file
|
|
||||||
go.work
|
|
||||||
go.work.sum
|
|
||||||
|
|
||||||
# env file
|
|
||||||
.env
|
|
||||||
|
|
||||||
# ---> JetBrains
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/**/usage.statistics.xml
|
|
||||||
.idea/**/dictionaries
|
|
||||||
.idea/**/shelf
|
|
||||||
|
|
||||||
# AWS User-specific
|
|
||||||
.idea/**/aws.xml
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
.idea/**/contentModel.xml
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
.idea/**/dbnavigator.xml
|
|
||||||
|
|
||||||
# Gradle
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# Gradle and Maven with auto-import
|
|
||||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
||||||
# since they will be recreated, and may cause churn. Uncomment if using
|
|
||||||
# auto-import.
|
|
||||||
# .idea/artifacts
|
|
||||||
# .idea/compiler.xml
|
|
||||||
# .idea/jarRepositories.xml
|
|
||||||
# .idea/modules.xml
|
|
||||||
# .idea/*.iml
|
|
||||||
# .idea/modules
|
|
||||||
# *.iml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-*/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
# File-based project format
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# SonarLint plugin
|
|
||||||
.idea/sonarlint/
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
# Editor-based Rest Client
|
|
||||||
.idea/httpRequests
|
|
||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
|
||||||
.idea/caches/build_file_checksums.ser
|
|
||||||
|
|
24
README.md
24
README.md
@@ -1,2 +1,26 @@
|
|||||||
# Go-TriTabula
|
# Go-TriTabula
|
||||||
|
|
||||||
|
这是一个使用Go语言实现的数据库三线表生成工具,用于从MySQL数据库中提取表结构信息并生成Word格式的三线表文档。
|
||||||
|
|
||||||
|
## 功能特点
|
||||||
|
|
||||||
|
- 连接MySQL数据库并获取表结构信息
|
||||||
|
- 将表结构信息转换为三线表格式
|
||||||
|
- 生成Word文档格式的三线表
|
||||||
|
- 支持自定义数据库连接参数
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
1. 配置`config/dbconfig.json`文件中的数据库连接信息
|
||||||
|
2. 运行主程序:`go run main.go`
|
||||||
|
3. 生成的Word文档将保存在程序运行目录下
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
Go-TriTabula/
|
||||||
|
├── config/ # 配置文件目录
|
||||||
|
├── entity/ # 实体定义
|
||||||
|
├── util/ # 工具类
|
||||||
|
└── main.go # 主程序入口
|
||||||
|
```
|
9
config/dbconfig.json
Normal file
9
config/dbconfig.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"driver": "mysql",
|
||||||
|
"url": "127.0.0.1:3306",
|
||||||
|
"database": "schisandra-cloud-album",
|
||||||
|
"username": "root",
|
||||||
|
"password": "1611",
|
||||||
|
"maxOpenConns": 100,
|
||||||
|
"maxIdleConns": 10
|
||||||
|
}
|
30
entity/entity.go
Normal file
30
entity/entity.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package entity
|
||||||
|
|
||||||
|
// Result 表示数据库表的结构信息
|
||||||
|
type Result struct {
|
||||||
|
TableSchema string `json:"tableSchema"`
|
||||||
|
TableName string `json:"tableName"`
|
||||||
|
TableDetails []TableDetail `json:"tableDetails"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableDetail 表示表中列的详细信息
|
||||||
|
type TableDetail struct {
|
||||||
|
ColumnName string `json:"columnName" field:"字段名"`
|
||||||
|
ColumnType string `json:"columnType" field:"类型"`
|
||||||
|
IsNullable string `json:"isNullable" field:"是否为空"`
|
||||||
|
ColumnKey string `json:"columnKey" field:"索引"`
|
||||||
|
ColumnDefault string `json:"columnDefault" field:"默认值"`
|
||||||
|
ColumnComment string `json:"columnComment" field:"说明"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFieldMapping 返回字段名与显示名称的映射
|
||||||
|
func GetFieldMapping() map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"ColumnName": "字段名",
|
||||||
|
"ColumnType": "类型",
|
||||||
|
"IsNullable": "是否为空",
|
||||||
|
"ColumnKey": "索引",
|
||||||
|
"ColumnDefault": "默认值",
|
||||||
|
"ColumnComment": "说明",
|
||||||
|
}
|
||||||
|
}
|
10
go.mod
Normal file
10
go.mod
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
module github.com/landaiqing/Go-TriTabula
|
||||||
|
|
||||||
|
go 1.24.2
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-sql-driver/mysql v1.9.2
|
||||||
|
github.com/landaiqing/go-dockit v0.1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require filippo.io/edwards25519 v1.1.0 // indirect
|
6
go.sum
Normal file
6
go.sum
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
|
github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU=
|
||||||
|
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||||
|
github.com/landaiqing/go-dockit v0.1.0 h1:GIUTdV2xQI/7M1xERup870dsdCcp5LPoeTMCP9An1BU=
|
||||||
|
github.com/landaiqing/go-dockit v0.1.0/go.mod h1:OCdoK6iw0MGcr+5WaqHgWkFALhZPib8H/nkywfeJCww=
|
71
main.go
Normal file
71
main.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/landaiqing/Go-TriTabula/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 解析命令行参数
|
||||||
|
var configPath string
|
||||||
|
var outputFile string
|
||||||
|
|
||||||
|
// 设置命令行参数
|
||||||
|
flag.StringVar(&configPath, "config", "config/dbconfig.json", "数据库配置文件路径")
|
||||||
|
flag.StringVar(&outputFile, "output", "output.docx", "输出文件名")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// 获取当前工作目录
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("获取工作目录失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载数据库配置
|
||||||
|
configFullPath := filepath.Join(wd, configPath)
|
||||||
|
config, err := util.LoadDBConfig(configFullPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("加载数据库配置失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("正在连接数据库: %s\n", config.Database)
|
||||||
|
|
||||||
|
// 获取数据库连接
|
||||||
|
db, err := util.GetDatabaseConnection(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("连接数据库失败: %v", err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
fmt.Println("数据库连接成功")
|
||||||
|
|
||||||
|
// 获取表结构信息
|
||||||
|
fmt.Printf("正在获取数据库 %s 的表结构信息...\n", config.Database)
|
||||||
|
results, err := util.GetTableDetails(db, config.Database)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("获取表结构信息失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("成功获取 %d 个表的结构信息\n", len(results))
|
||||||
|
|
||||||
|
// 创建导出工具
|
||||||
|
exportWord := &util.ExportWord{}
|
||||||
|
|
||||||
|
// 创建文档
|
||||||
|
fmt.Println("正在生成Word文档...")
|
||||||
|
doc := exportWord.CreateDocument(results)
|
||||||
|
|
||||||
|
// 导出文档
|
||||||
|
outputFullPath := filepath.Join(wd, outputFile)
|
||||||
|
err = exportWord.ExportToFile(doc, outputFullPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("导出文档失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("文档生成成功: %s\n", outputFullPath)
|
||||||
|
}
|
177
util/database.go
Normal file
177
util/database.go
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log" // 添加 log 包
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/landaiqing/Go-TriTabula/entity"
|
||||||
|
|
||||||
|
"github.com/go-sql-driver/mysql"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DBConfig 数据库配置结构
|
||||||
|
type DBConfig struct {
|
||||||
|
Driver string `json:"driver"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Database string `json:"database"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
MaxOpenConns int `json:"maxOpenConns"`
|
||||||
|
MaxIdleConns int `json:"maxIdleConns"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadDBConfig 从配置文件加载数据库配置
|
||||||
|
func LoadDBConfig(configPath string) (*DBConfig, error) {
|
||||||
|
absPath, err := filepath.Abs(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("获取配置文件绝对路径失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(absPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("打开配置文件失败: %v", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
byteValue, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("读取配置文件失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var config DBConfig
|
||||||
|
if err := json.Unmarshal(byteValue, &config); err != nil {
|
||||||
|
return nil, fmt.Errorf("解析配置文件失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDatabaseConnection 获取数据库连接
|
||||||
|
func GetDatabaseConnection(config *DBConfig) (*sql.DB, error) {
|
||||||
|
// 配置MySQL连接
|
||||||
|
mysqlConfig := mysql.Config{
|
||||||
|
User: config.Username,
|
||||||
|
Passwd: config.Password,
|
||||||
|
Net: "tcp",
|
||||||
|
Addr: config.URL,
|
||||||
|
DBName: config.Database,
|
||||||
|
AllowNativePasswords: true,
|
||||||
|
ParseTime: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开数据库连接
|
||||||
|
db, err := sql.Open("mysql", mysqlConfig.FormatDSN())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("连接数据库失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置连接池参数
|
||||||
|
db.SetMaxOpenConns(config.MaxOpenConns)
|
||||||
|
db.SetMaxIdleConns(config.MaxIdleConns)
|
||||||
|
|
||||||
|
// 测试连接
|
||||||
|
if err := db.Ping(); err != nil {
|
||||||
|
return nil, fmt.Errorf("测试数据库连接失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return db, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTableDetails 获取数据库表结构详情
|
||||||
|
func GetTableDetails(db *sql.DB, databaseName string) ([]entity.Result, error) {
|
||||||
|
query := `
|
||||||
|
SELECT table_schema, table_name, column_name, column_type, column_key,
|
||||||
|
is_nullable, column_default, column_comment, character_set_name, EXTRA
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = ?
|
||||||
|
ORDER BY table_name, ORDINAL_POSITION
|
||||||
|
`
|
||||||
|
|
||||||
|
// 执行查询
|
||||||
|
rows, err := db.Query(query, databaseName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("查询表结构失败: %v", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
// 用于存储结果的映射和列表
|
||||||
|
tableMap := make(map[string]int) // Map tableName to index in results slice
|
||||||
|
var results []entity.Result
|
||||||
|
|
||||||
|
// 遍历查询结果
|
||||||
|
for rows.Next() {
|
||||||
|
var tableSchema, tableName, columnName, columnType, columnKey string
|
||||||
|
var isNullable, columnDefault, columnComment, characterSetName, extra sql.NullString
|
||||||
|
|
||||||
|
// 扫描行数据
|
||||||
|
err := rows.Scan(
|
||||||
|
&tableSchema, &tableName, &columnName, &columnType, &columnKey,
|
||||||
|
&isNullable, &columnDefault, &columnComment, &characterSetName, &extra,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("扫描行数据失败: %v", err)
|
||||||
|
}
|
||||||
|
log.Printf("读取到行: Table=%s, Column=%s\n", tableName, columnName) // 添加行读取日志
|
||||||
|
|
||||||
|
// 处理表信息
|
||||||
|
idx, exists := tableMap[tableName]
|
||||||
|
if !exists {
|
||||||
|
// 创建新的表结果并添加到 results slice
|
||||||
|
newResult := entity.Result{
|
||||||
|
TableSchema: tableSchema,
|
||||||
|
TableName: tableName,
|
||||||
|
TableDetails: []entity.TableDetail{},
|
||||||
|
}
|
||||||
|
results = append(results, newResult)
|
||||||
|
idx = len(results) - 1 // Get the index of the newly added result
|
||||||
|
tableMap[tableName] = idx // Store the index in the map
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理列信息
|
||||||
|
columnDefaultValue := "无"
|
||||||
|
if columnDefault.Valid {
|
||||||
|
columnDefaultValue = columnDefault.String
|
||||||
|
}
|
||||||
|
|
||||||
|
columnKeyValue := "无"
|
||||||
|
if columnKey != "" {
|
||||||
|
columnKeyValue = columnKey
|
||||||
|
}
|
||||||
|
|
||||||
|
columnCommentValue := ""
|
||||||
|
if columnComment.Valid {
|
||||||
|
columnCommentValue = columnComment.String
|
||||||
|
}
|
||||||
|
|
||||||
|
isNullableValue := "NO"
|
||||||
|
if isNullable.Valid {
|
||||||
|
isNullableValue = isNullable.String
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建列详情
|
||||||
|
tableDetail := entity.TableDetail{
|
||||||
|
ColumnName: columnName,
|
||||||
|
ColumnType: columnType,
|
||||||
|
ColumnKey: columnKeyValue,
|
||||||
|
IsNullable: isNullableValue,
|
||||||
|
ColumnDefault: columnDefaultValue,
|
||||||
|
ColumnComment: columnCommentValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加到表的列列表 (直接修改 results 切片中的元素)
|
||||||
|
results[idx].TableDetails = append(results[idx].TableDetails, tableDetail)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有错误发生
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, fmt.Errorf("遍历结果集时发生错误: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("GetTableDetails 完成, 共处理 %d 个表的结果。\n", len(results)) // 添加最终结果日志
|
||||||
|
return results, nil
|
||||||
|
}
|
162
util/export_word.go
Normal file
162
util/export_word.go
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/landaiqing/Go-TriTabula/entity"
|
||||||
|
|
||||||
|
"github.com/landaiqing/go-dockit/document"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExportWord 用于导出Word文档的工具结构体
|
||||||
|
type ExportWord struct{}
|
||||||
|
|
||||||
|
// CreateDocument 创建一个新的Word文档
|
||||||
|
func (ew *ExportWord) CreateDocument(results []entity.Result) *document.Document {
|
||||||
|
// 创建新文档
|
||||||
|
doc := document.NewDocument()
|
||||||
|
|
||||||
|
// 设置文档属性
|
||||||
|
doc.SetTitle("数据库三线表")
|
||||||
|
doc.SetCreator("Go-TriTabula")
|
||||||
|
doc.SetDescription("使用go-dockit库创建数据库三线表")
|
||||||
|
|
||||||
|
// 为每个表结果创建表格和标题
|
||||||
|
for _, result := range results {
|
||||||
|
// 创建表名标题段落
|
||||||
|
tableTitlePara := doc.AddParagraph()
|
||||||
|
tableTitlePara.SetAlignment("center")
|
||||||
|
tableTitlePara.SetSpacingAfter(0)
|
||||||
|
tableTitlePara.SetSpacingBefore(0)
|
||||||
|
tableTitlePara.SetLineSpacing(1.5, "auto") // 设置1.5倍行距
|
||||||
|
tableTitleRun := tableTitlePara.AddRun()
|
||||||
|
tableTitleRun.AddText(result.TableName)
|
||||||
|
tableTitleRun.SetBold(true)
|
||||||
|
tableTitleRun.SetFontSize(21) // 五号字体约为10.5磅(21)
|
||||||
|
tableTitleRun.SetFontFamily("宋体")
|
||||||
|
|
||||||
|
// 获取字段映射
|
||||||
|
fieldMapping := entity.GetFieldMapping()
|
||||||
|
fieldNames := []string{"ColumnName", "ColumnType", "IsNullable", "ColumnKey", "ColumnDefault", "ColumnComment"}
|
||||||
|
|
||||||
|
// 创建表格
|
||||||
|
table := doc.AddTable(len(result.TableDetails)+1, len(fieldNames))
|
||||||
|
table.SetWidth("100%", "pct") // 与文字齐宽
|
||||||
|
table.SetAlignment("center")
|
||||||
|
|
||||||
|
// 填充表头
|
||||||
|
for i, fieldName := range fieldNames {
|
||||||
|
cellPara := table.Rows[0].Cells[i].AddParagraph()
|
||||||
|
cellPara.SetAlignment("center")
|
||||||
|
cellPara.SetLineSpacing(1.5, "auto") // 1.5倍行距
|
||||||
|
cellRun := cellPara.AddRun()
|
||||||
|
cellRun.AddText(fieldMapping[fieldName])
|
||||||
|
cellRun.SetBold(false)
|
||||||
|
cellRun.SetFontSize(21) // 五号字体
|
||||||
|
cellRun.SetFontFamily("宋体")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 填充数据行
|
||||||
|
for i, detail := range result.TableDetails {
|
||||||
|
// 字段名
|
||||||
|
para := table.Rows[i+1].Cells[0].AddParagraph()
|
||||||
|
para.SetAlignment("center")
|
||||||
|
para.SetLineSpacing(1.5, "auto") // 1.5倍行距
|
||||||
|
cellRun := para.AddRun()
|
||||||
|
cellRun.AddText(detail.ColumnName)
|
||||||
|
cellRun.SetFontSize(21) // 五号字体
|
||||||
|
cellRun.SetFontFamily("Times New Roman")
|
||||||
|
|
||||||
|
// 类型
|
||||||
|
para = table.Rows[i+1].Cells[1].AddParagraph()
|
||||||
|
para.SetAlignment("center")
|
||||||
|
para.SetLineSpacing(1.5, "auto")
|
||||||
|
cellRun = para.AddRun()
|
||||||
|
cellRun.AddText(detail.ColumnType)
|
||||||
|
cellRun.SetFontSize(21)
|
||||||
|
cellRun.SetFontFamily("Times New Roman") // 英文使用Times New Roman
|
||||||
|
|
||||||
|
// 是否为空
|
||||||
|
para = table.Rows[i+1].Cells[2].AddParagraph()
|
||||||
|
para.SetAlignment("center")
|
||||||
|
para.SetLineSpacing(1.5, "auto")
|
||||||
|
cellRun = para.AddRun()
|
||||||
|
// 将NO和YES转换为更易读的否和是
|
||||||
|
isNullableText := "否"
|
||||||
|
if detail.IsNullable == "YES" {
|
||||||
|
isNullableText = "是"
|
||||||
|
}
|
||||||
|
cellRun.AddText(isNullableText)
|
||||||
|
cellRun.SetFontSize(21)
|
||||||
|
cellRun.SetFontFamily("宋体")
|
||||||
|
|
||||||
|
// 索引
|
||||||
|
para = table.Rows[i+1].Cells[3].AddParagraph()
|
||||||
|
para.SetAlignment("center")
|
||||||
|
para.SetLineSpacing(1.5, "auto")
|
||||||
|
cellRun = para.AddRun()
|
||||||
|
cellRun.AddText(detail.ColumnKey)
|
||||||
|
cellRun.SetFontSize(21)
|
||||||
|
cellRun.SetFontFamily("宋体")
|
||||||
|
|
||||||
|
// 默认值
|
||||||
|
para = table.Rows[i+1].Cells[4].AddParagraph()
|
||||||
|
para.SetAlignment("center")
|
||||||
|
para.SetLineSpacing(1.5, "auto")
|
||||||
|
cellRun = para.AddRun()
|
||||||
|
// 将"无"替换为"NULL",使其更符合数据库术语
|
||||||
|
defaultValue := "NULL"
|
||||||
|
if detail.ColumnDefault != "无" {
|
||||||
|
defaultValue = detail.ColumnDefault
|
||||||
|
}
|
||||||
|
cellRun.AddText(defaultValue)
|
||||||
|
cellRun.SetFontSize(21)
|
||||||
|
cellRun.SetFontFamily("宋体")
|
||||||
|
|
||||||
|
// 说明
|
||||||
|
para = table.Rows[i+1].Cells[5].AddParagraph()
|
||||||
|
para.SetAlignment("center")
|
||||||
|
para.SetLineSpacing(1.5, "auto")
|
||||||
|
cellRun = para.AddRun()
|
||||||
|
cellRun.AddText(detail.ColumnComment)
|
||||||
|
cellRun.SetFontSize(21)
|
||||||
|
cellRun.SetFontFamily("宋体")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置三线表样式
|
||||||
|
// 1. 首先清除所有默认边框
|
||||||
|
table.SetBorders("all", "", 0, "")
|
||||||
|
// 2. 顶线(表格顶部边框),1.5磅
|
||||||
|
table.SetBorders("top", "single", 10, "000000")
|
||||||
|
// 3. 表头分隔线(第一行底部边框),1磅
|
||||||
|
for i := 0; i < len(fieldNames); i++ {
|
||||||
|
table.Rows[0].Cells[i].SetBorders("bottom", "single", 4, "000000")
|
||||||
|
}
|
||||||
|
// 4. 底线(表格底部边框),1.5磅
|
||||||
|
table.SetBorders("bottom", "single", 10, "000000")
|
||||||
|
// 5. 显式设置内部边框为"none"
|
||||||
|
table.SetBorders("insideH", "none", 0, "000000")
|
||||||
|
table.SetBorders("insideV", "none", 0, "000000")
|
||||||
|
|
||||||
|
// 添加空行
|
||||||
|
doc.AddParagraph()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加页脚(页码)
|
||||||
|
footer := doc.AddFooterWithReference("default")
|
||||||
|
footer.AddPageNumber()
|
||||||
|
|
||||||
|
return doc
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportToFile 将文档导出到文件
|
||||||
|
func (ew *ExportWord) ExportToFile(doc *document.Document, filePath string) error {
|
||||||
|
err := doc.Save(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("保存文档失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("文档已成功保存到: %s", filePath)
|
||||||
|
return nil
|
||||||
|
}
|
Reference in New Issue
Block a user