package document import ( "fmt" "strings" ) // Run 表示Word文档中的文本运行 type Run struct { Text string Properties *RunProperties BreakType string Drawing *Drawing Field *Field } // Field 表示Word文档中的域 type Field struct { Type string // begin, separate, end Code string // 域代码 } // RunProperties 表示文本运行的属性 type RunProperties struct { Bold bool // 粗体 Italic bool // 斜体 Underline string // 下划线类型:single, double, thick, dotted, dash, etc. Strike bool // 删除线 DoubleStrike bool // 双删除线 Superscript bool // 上标 Subscript bool // 下标 FontSize int // 字号,单位为半点 FontFamily string // 字体 Color string // 颜色,格式为RRGGBB Highlight string // 突出显示颜色 Caps bool // 全部大写 SmallCaps bool // 小型大写 CharacterSpacing int // 字符间距 Shading *Shading // 底纹 VertAlign string // 垂直对齐方式:baseline, superscript, subscript RTL bool // 从右到左文本方向 Language string // 语言 } // BreakType 表示分隔符类型 const ( BreakTypePage = "page" // 分页符 BreakTypeColumn = "column" // 分栏符 BreakTypeSection = "section" // 分节符 BreakTypeLine = "textWrapping" // 换行符 ) // NewRun 创建一个新的文本运行 func NewRun() *Run { return &Run{ Text: "", Properties: &RunProperties{ FontSize: 22, // 默认11磅 (22半点) FontFamily: "Calibri", Color: "000000", }, } } // AddText 向文本运行添加文本 func (r *Run) AddText(text string) *Run { r.Text = text return r } // AddBreak 向文本运行添加分隔符 func (r *Run) AddBreak(breakType string) *Run { r.BreakType = breakType return r } // AddDrawing 向文本运行添加图形 func (r *Run) AddDrawing(drawing *Drawing) *Run { r.Drawing = drawing return r } // SetBold 设置粗体 func (r *Run) SetBold(bold bool) *Run { r.Properties.Bold = bold return r } // SetItalic 设置斜体 func (r *Run) SetItalic(italic bool) *Run { r.Properties.Italic = italic return r } // SetUnderline 设置下划线 func (r *Run) SetUnderline(underline string) *Run { r.Properties.Underline = underline return r } // SetStrike 设置删除线 func (r *Run) SetStrike(strike bool) *Run { r.Properties.Strike = strike return r } // SetDoubleStrike 设置双删除线 func (r *Run) SetDoubleStrike(doubleStrike bool) *Run { r.Properties.DoubleStrike = doubleStrike return r } // SetSuperscript 设置上标 func (r *Run) SetSuperscript(superscript bool) *Run { r.Properties.Superscript = superscript return r } // SetSubscript 设置下标 func (r *Run) SetSubscript(subscript bool) *Run { r.Properties.Subscript = subscript return r } // SetFontSize 设置字号 func (r *Run) SetFontSize(fontSize int) *Run { r.Properties.FontSize = fontSize return r } // SetFontFamily 设置字体 func (r *Run) SetFontFamily(fontFamily string) *Run { r.Properties.FontFamily = fontFamily return r } // SetFontFamilyForRunes 为特定字符设置字体 // 该方法允许为特定的字符序列设置不同的字体 func (r *Run) SetFontFamilyForRunes(fontFamily string, runes []rune) *Run { if runes == nil || len(runes) == 0 { r.Properties.FontFamily = fontFamily return r } // 将当前文本中的指定字符设置为指定字体 runeText := string(runes) if strings.Contains(r.Text, runeText) { // 如果当前文本包含指定字符,设置字体 // 注意:这是一个简化实现,只是将整个Run的字体设置为指定字体 // 实际上,为了真正支持混合字体,需要将Run拆分为多个不同字体的Run // 但这需要对段落对象的引用,当前结构不支持这种操作 r.Properties.FontFamily = fontFamily } return r } // SetColor 设置颜色 func (r *Run) SetColor(color string) *Run { r.Properties.Color = color return r } // SetHighlight 设置突出显示颜色 func (r *Run) SetHighlight(highlight string) *Run { r.Properties.Highlight = highlight return r } // SetCaps 设置全部大写 func (r *Run) SetCaps(caps bool) *Run { r.Properties.Caps = caps return r } // SetSmallCaps 设置小型大写 func (r *Run) SetSmallCaps(smallCaps bool) *Run { r.Properties.SmallCaps = smallCaps return r } // SetCharacterSpacing 设置字符间距 func (r *Run) SetCharacterSpacing(spacing int) *Run { r.Properties.CharacterSpacing = spacing return r } // SetShading 设置底纹 func (r *Run) SetShading(fill, color, pattern string) *Run { r.Properties.Shading = &Shading{ Fill: fill, Color: color, Pattern: pattern, } return r } // SetVertAlign 设置垂直对齐方式 func (r *Run) SetVertAlign(vertAlign string) *Run { r.Properties.VertAlign = vertAlign return r } // SetRTL 设置从右到左文本方向 func (r *Run) SetRTL(rtl bool) *Run { r.Properties.RTL = rtl return r } // SetLanguage 设置语言 func (r *Run) SetLanguage(language string) *Run { r.Properties.Language = language return r } // AddField 添加Word域 func (r *Run) AddField(fieldType string, fieldCode string) *Run { r.Text = "" r.Field = &Field{ Type: fieldType, Code: fieldCode, } return r } // AddTab 添加制表符到文本运行中 func (r *Run) AddTab() *Run { // 在OOXML中,制表符被表示为元素 // 这里我们使用一个特殊标记,在ToXML时会被替换为制表符标签 r.Text += "\t" return r } // AddPageNumber 添加页码域 // Deprecated: 建议使用Document.AddPageNumberParagraph或Footer.AddPageNumber方法 func (r *Run) AddPageNumber() *Run { // 注意:此方法生成的页码字段可能不完整 // 推荐使用Document.AddPageNumberParagraph或Footer.AddPageNumber方法 // 创建一个完整的页码字段,包含所有需要的部分 // 返回一个标准的域开始标记 return r.AddField("begin", "PAGE") } // findParagraph 尝试找到当前Run所在的段落 func (r *Run) findParagraph() *Paragraph { // 这个方法可能需要访问Document实例来找到包含当前Run的段落 // 由于目前的结构限制,我们简单地返回nil,表示找不到段落 // 在实际完整实现中,应该找到文档中包含此Run的段落 return nil } // ToXML 将Run转换为XML func (r *Run) ToXML() string { xml := "" // 添加运行属性 - 严格按照Word XML规范顺序 xml += "" // 运行样式(缺失,预留位置) // 1. 字体 if r.Properties.FontFamily != "" { xml += fmt.Sprintf("", r.Properties.FontFamily, r.Properties.FontFamily, r.Properties.FontFamily, r.Properties.FontFamily) } // 2. 加粗 if r.Properties.Bold { xml += "" // 3. 复杂文本加粗 xml += "" } // 4. 斜体 if r.Properties.Italic { xml += "" // 5. 复杂文本斜体 xml += "" } // 6. 全部大写 if r.Properties.Caps { xml += "" } // 7. 小型大写 if r.Properties.SmallCaps { xml += "" } // 8. 删除线 if r.Properties.Strike { xml += "" } // 9. 双删除线 if r.Properties.DoubleStrike { xml += "" } // 10-18. 其他格式(outline, shadow, emboss等,缺失,预留位置) // 19. 颜色 if r.Properties.Color != "" { xml += fmt.Sprintf("", r.Properties.Color) } // 20. 字符间距 if r.Properties.CharacterSpacing != 0 { xml += fmt.Sprintf("", r.Properties.CharacterSpacing) } // 21-23. 其他属性(缺失,预留位置) // 24. 字号 if r.Properties.FontSize > 0 { xml += fmt.Sprintf("", r.Properties.FontSize) // 25. 复杂文本字号 xml += fmt.Sprintf("", r.Properties.FontSize) } // 26. 突出显示 if r.Properties.Highlight != "" { xml += fmt.Sprintf("", r.Properties.Highlight) } // 27. 下划线 if r.Properties.Underline != "" { xml += fmt.Sprintf("", r.Properties.Underline) } // 28-31. 其他属性(缺失,预留位置) // 32. 上标/下标 if r.Properties.Superscript { xml += "" } else if r.Properties.Subscript { xml += "" } else if r.Properties.VertAlign != "" { xml += fmt.Sprintf("", r.Properties.VertAlign) } // 33. 从右到左文本方向 if r.Properties.RTL { xml += "" } // 34-35. 其他属性(缺失,预留位置) // 36. 语言 if r.Properties.Language != "" { xml += fmt.Sprintf("", r.Properties.Language) } // 底纹(shd应该在位置30) if r.Properties.Shading != nil { xml += fmt.Sprintf("", r.Properties.Shading.Pattern, r.Properties.Shading.Fill, r.Properties.Shading.Color) } xml += "" // 处理域 if r.Field != nil { switch r.Field.Type { case "begin": xml += fmt.Sprintf("%s", r.Field.Code) case "separate": xml += "" case "end": xml += "" } } else if r.Drawing != nil { // 添加图形元素 xml += r.Drawing.ToXML() } else if r.BreakType != "" { // 添加分隔符 switch r.BreakType { case BreakTypePage: xml += "" case BreakTypeColumn: xml += "" case BreakTypeSection: xml += "" case BreakTypeLine: xml += "" } } else { // 处理文本内容 // 特殊处理:制表符 if r.Text != "" { var textParts []string for _, char := range r.Text { if char == '\t' { // 如果是制表符,关闭当前文本,添加制表符标签,然后重新开始文本 if len(textParts) > 0 { xml += fmt.Sprintf("%s", escapeXML(textParts[len(textParts)-1])) textParts = textParts[:len(textParts)-1] } xml += "" textParts = append(textParts, "") } else { // 如果是普通字符,添加到当前文本部分 if len(textParts) == 0 { textParts = append(textParts, "") } textParts[len(textParts)-1] += string(char) } } // 处理最后一个文本部分 for _, part := range textParts { if part != "" { xml += fmt.Sprintf("%s", escapeXML(part)) } } } } xml += "" return xml } // escapeXML 转义XML文本中的特殊字符 func escapeXML(s string) string { s = strings.ReplaceAll(s, "&", "&") s = strings.ReplaceAll(s, "<", "<") s = strings.ReplaceAll(s, ">", ">") s = strings.ReplaceAll(s, "\"", """) s = strings.ReplaceAll(s, "'", "'") return s }