🎉 Initial commit

This commit is contained in:
2025-04-16 16:12:33 +08:00
commit af9b26fa6c
28 changed files with 6318 additions and 0 deletions

299
document/paragraph.go Normal file
View File

@@ -0,0 +1,299 @@
package document
import "fmt"
// Paragraph 表示Word文档中的段落
type Paragraph struct {
Runs []*Run
Properties *ParagraphProperties
}
// ParagraphProperties 表示段落的属性
type ParagraphProperties struct {
Alignment string // left, center, right, justified
IndentLeft int // 左缩进单位为twip (1/20 point)
IndentRight int // 右缩进
IndentFirstLine int // 首行缩进
SpacingBefore int // 段前间距
SpacingAfter int // 段后间距
SpacingLine int // 行间距
SpacingLineRule string // auto, exact, atLeast
KeepNext bool // 与下段同页
KeepLines bool // 段中不分页
PageBreakBefore bool // 段前分页
WidowControl bool // 孤行控制
OutlineLevel int // 大纲级别
StyleID string // 样式ID
NumID int // 编号ID
NumLevel int // 编号级别
BorderTop *Border
BorderBottom *Border
BorderLeft *Border
BorderRight *Border
Shading *Shading
}
// Border 表示边框
type Border struct {
Style string // single, double, dotted, dashed, etc.
Size int // 边框宽度单位为1/8点
Color string // 边框颜色格式为RRGGBB
Space int // 边框与文本的距离
}
// Shading 表示底纹
type Shading struct {
Fill string // 填充颜色
Color string // 文本颜色
Pattern string // 底纹样式
}
// NewParagraph 创建一个新的段落
func NewParagraph() *Paragraph {
return &Paragraph{
Runs: make([]*Run, 0),
Properties: &ParagraphProperties{
Alignment: "left",
WidowControl: true,
SpacingLineRule: "auto",
},
}
}
// AddRun 向段落添加一个文本运行并返回它
func (p *Paragraph) AddRun() *Run {
r := NewRun()
p.Runs = append(p.Runs, r)
return r
}
// AddText 向段落添加文本
func (p *Paragraph) AddText(text string) *Run {
return p.AddRun().AddText(text)
}
// SetAlignment 设置段落对齐方式
func (p *Paragraph) SetAlignment(alignment string) *Paragraph {
p.Properties.Alignment = alignment
return p
}
// SetIndentLeft 设置左缩进
func (p *Paragraph) SetIndentLeft(indent int) *Paragraph {
p.Properties.IndentLeft = indent
return p
}
// SetIndentRight 设置右缩进
func (p *Paragraph) SetIndentRight(indent int) *Paragraph {
p.Properties.IndentRight = indent
return p
}
// SetIndentFirstLine 设置首行缩进
func (p *Paragraph) SetIndentFirstLine(indent int) *Paragraph {
p.Properties.IndentFirstLine = indent
return p
}
// SetSpacingBefore 设置段前间距
func (p *Paragraph) SetSpacingBefore(spacing int) *Paragraph {
p.Properties.SpacingBefore = spacing
return p
}
// SetSpacingAfter 设置段后间距
func (p *Paragraph) SetSpacingAfter(spacing int) *Paragraph {
p.Properties.SpacingAfter = spacing
return p
}
// SetSpacingLine 设置行间距
func (p *Paragraph) SetSpacingLine(spacing int, rule string) *Paragraph {
p.Properties.SpacingLine = spacing
p.Properties.SpacingLineRule = rule
return p
}
// SetKeepNext 设置与下段同页
func (p *Paragraph) SetKeepNext(keepNext bool) *Paragraph {
p.Properties.KeepNext = keepNext
return p
}
// SetKeepLines 设置段中不分页
func (p *Paragraph) SetKeepLines(keepLines bool) *Paragraph {
p.Properties.KeepLines = keepLines
return p
}
// SetPageBreakBefore 设置段前分页
func (p *Paragraph) SetPageBreakBefore(pageBreakBefore bool) *Paragraph {
p.Properties.PageBreakBefore = pageBreakBefore
return p
}
// SetStyleID 设置样式ID
func (p *Paragraph) SetStyleID(styleID string) *Paragraph {
p.Properties.StyleID = styleID
return p
}
// SetNumbering 设置编号
func (p *Paragraph) SetNumbering(numID, numLevel int) *Paragraph {
p.Properties.NumID = numID
p.Properties.NumLevel = numLevel
return p
}
// SetBorder 设置边框
func (p *Paragraph) SetBorder(position string, style string, size int, color string, space int) *Paragraph {
border := &Border{
Style: style,
Size: size,
Color: color,
Space: space,
}
switch position {
case "top":
p.Properties.BorderTop = border
case "bottom":
p.Properties.BorderBottom = border
case "left":
p.Properties.BorderLeft = border
case "right":
p.Properties.BorderRight = border
}
return p
}
// SetShading 设置底纹
func (p *Paragraph) SetShading(fill, color, pattern string) *Paragraph {
p.Properties.Shading = &Shading{
Fill: fill,
Color: color,
Pattern: pattern,
}
return p
}
// ToXML 将段落转换为XML
func (p *Paragraph) ToXML() string {
xml := "<w:p>"
// 添加段落属性
xml += "<w:pPr>"
// 对齐方式
if p.Properties.Alignment != "" {
xml += "<w:jc w:val=\"" + p.Properties.Alignment + "\" />"
}
// 缩进
if p.Properties.IndentLeft > 0 || p.Properties.IndentRight > 0 || p.Properties.IndentFirstLine > 0 {
xml += "<w:ind"
if p.Properties.IndentLeft > 0 {
xml += " w:left=\"" + fmt.Sprintf("%d", p.Properties.IndentLeft) + "\""
}
if p.Properties.IndentRight > 0 {
xml += " w:right=\"" + fmt.Sprintf("%d", p.Properties.IndentRight) + "\""
}
if p.Properties.IndentFirstLine > 0 {
xml += " w:firstLine=\"" + fmt.Sprintf("%d", p.Properties.IndentFirstLine) + "\""
}
xml += " />"
}
// 间距
if p.Properties.SpacingBefore > 0 || p.Properties.SpacingAfter > 0 || p.Properties.SpacingLine > 0 {
xml += "<w:spacing"
if p.Properties.SpacingBefore > 0 {
xml += " w:before=\"" + fmt.Sprintf("%d", p.Properties.SpacingBefore) + "\""
}
if p.Properties.SpacingAfter > 0 {
xml += " w:after=\"" + fmt.Sprintf("%d", p.Properties.SpacingAfter) + "\""
}
if p.Properties.SpacingLine > 0 {
xml += " w:line=\"" + fmt.Sprintf("%d", p.Properties.SpacingLine) + "\""
xml += " w:lineRule=\"" + p.Properties.SpacingLineRule + "\""
}
xml += " />"
}
// 分页控制
if p.Properties.KeepNext {
xml += "<w:keepNext />"
}
if p.Properties.KeepLines {
xml += "<w:keepLines />"
}
if p.Properties.PageBreakBefore {
xml += "<w:pageBreakBefore />"
}
if p.Properties.WidowControl {
xml += "<w:widowControl />"
}
// 样式
if p.Properties.StyleID != "" {
xml += "<w:pStyle w:val=\"" + p.Properties.StyleID + "\" />"
}
// 编号
if p.Properties.NumID > 0 {
xml += "<w:numPr>"
xml += "<w:numId w:val=\"" + fmt.Sprintf("%d", p.Properties.NumID) + "\" />"
xml += "<w:ilvl w:val=\"" + fmt.Sprintf("%d", p.Properties.NumLevel) + "\" />"
xml += "</w:numPr>"
}
// 边框
if p.Properties.BorderTop != nil || p.Properties.BorderBottom != nil ||
p.Properties.BorderLeft != nil || p.Properties.BorderRight != nil {
xml += "<w:pBdr>"
if p.Properties.BorderTop != nil {
xml += "<w:top w:val=\"" + p.Properties.BorderTop.Style + "\""
xml += " w:sz=\"" + fmt.Sprintf("%d", p.Properties.BorderTop.Size) + "\""
xml += " w:space=\"" + fmt.Sprintf("%d", p.Properties.BorderTop.Space) + "\""
xml += " w:color=\"" + p.Properties.BorderTop.Color + "\" />"
}
if p.Properties.BorderBottom != nil {
xml += "<w:bottom w:val=\"" + p.Properties.BorderBottom.Style + "\""
xml += " w:sz=\"" + fmt.Sprintf("%d", p.Properties.BorderBottom.Size) + "\""
xml += " w:space=\"" + fmt.Sprintf("%d", p.Properties.BorderBottom.Space) + "\""
xml += " w:color=\"" + p.Properties.BorderBottom.Color + "\" />"
}
if p.Properties.BorderLeft != nil {
xml += "<w:left w:val=\"" + p.Properties.BorderLeft.Style + "\""
xml += " w:sz=\"" + fmt.Sprintf("%d", p.Properties.BorderLeft.Size) + "\""
xml += " w:space=\"" + fmt.Sprintf("%d", p.Properties.BorderLeft.Space) + "\""
xml += " w:color=\"" + p.Properties.BorderLeft.Color + "\" />"
}
if p.Properties.BorderRight != nil {
xml += "<w:right w:val=\"" + p.Properties.BorderRight.Style + "\""
xml += " w:sz=\"" + fmt.Sprintf("%d", p.Properties.BorderRight.Size) + "\""
xml += " w:space=\"" + fmt.Sprintf("%d", p.Properties.BorderRight.Space) + "\""
xml += " w:color=\"" + p.Properties.BorderRight.Color + "\" />"
}
xml += "</w:pBdr>"
}
// 底纹
if p.Properties.Shading != nil {
xml += "<w:shd w:val=\"" + p.Properties.Shading.Pattern + "\""
xml += " w:fill=\"" + p.Properties.Shading.Fill + "\""
xml += " w:color=\"" + p.Properties.Shading.Color + "\" />"
}
xml += "</w:pPr>"
// 添加所有Run的XML
for _, run := range p.Runs {
xml += run.ToXML()
}
xml += "</w:p>"
return xml
}