🎨 Refactored XML generation logic and fixed content type override issues
This commit is contained in:
@@ -130,7 +130,19 @@ func (b *Body) ToXML() string {
|
||||
}
|
||||
|
||||
// 添加节属性
|
||||
xml += "<w:sectPr>"
|
||||
xml += "<w:sectPr xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"
|
||||
|
||||
// 页眉引用
|
||||
for _, headerRef := range b.SectionProperties.HeaderReference {
|
||||
xml += fmt.Sprintf("<w:headerReference w:type=\"%s\" r:id=\"%s\" />",
|
||||
headerRef.Type, headerRef.ID)
|
||||
}
|
||||
|
||||
// 页脚引用
|
||||
for _, footerRef := range b.SectionProperties.FooterReference {
|
||||
xml += fmt.Sprintf("<w:footerReference w:type=\"%s\" r:id=\"%s\" />",
|
||||
footerRef.Type, footerRef.ID)
|
||||
}
|
||||
|
||||
// 页面大小
|
||||
if b.SectionProperties.PageSize != nil {
|
||||
@@ -165,18 +177,6 @@ func (b *Body) ToXML() string {
|
||||
b.SectionProperties.DocGrid.LinePitch)
|
||||
}
|
||||
|
||||
// 页眉引用
|
||||
for _, headerRef := range b.SectionProperties.HeaderReference {
|
||||
xml += fmt.Sprintf("<w:headerReference w:type=\"%s\" r:id=\"%s\" />",
|
||||
headerRef.Type, headerRef.ID)
|
||||
}
|
||||
|
||||
// 页脚引用
|
||||
for _, footerRef := range b.SectionProperties.FooterReference {
|
||||
xml += fmt.Sprintf("<w:footerReference w:type=\"%s\" r:id=\"%s\" />",
|
||||
footerRef.Type, footerRef.ID)
|
||||
}
|
||||
|
||||
xml += "</w:sectPr>"
|
||||
|
||||
xml += "</w:body>"
|
||||
|
@@ -59,7 +59,7 @@ func (f *Footer) AddTable(rows, cols int) *Table {
|
||||
// ToXML 将页眉转换为XML
|
||||
func (h *Header) ToXML() string {
|
||||
xml := "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
|
||||
xml += "<w:hdr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">"
|
||||
xml += "<w:hdr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"
|
||||
|
||||
// 添加所有内容元素的XML
|
||||
for _, content := range h.Content {
|
||||
@@ -78,7 +78,7 @@ func (h *Header) ToXML() string {
|
||||
// ToXML 将页脚转换为XML
|
||||
func (f *Footer) ToXML() string {
|
||||
xml := "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
|
||||
xml += "<w:ftr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">"
|
||||
xml += "<w:ftr xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"
|
||||
|
||||
// 添加所有内容元素的XML
|
||||
for _, content := range f.Content {
|
||||
|
@@ -186,43 +186,12 @@ func (p *Paragraph) ToXML() string {
|
||||
// 添加段落属性
|
||||
xml += "<w:pPr>"
|
||||
|
||||
// 对齐方式
|
||||
if p.Properties.Alignment != "" {
|
||||
xml += "<w:jc w:val=\"" + p.Properties.Alignment + "\" />"
|
||||
// 样式 (必须在最前面)
|
||||
if p.Properties.StyleID != "" {
|
||||
xml += fmt.Sprintf("<w:pStyle w:val=\"%s\" />", p.Properties.StyleID)
|
||||
}
|
||||
|
||||
// 缩进
|
||||
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 />"
|
||||
}
|
||||
@@ -236,16 +205,11 @@ func (p *Paragraph) ToXML() string {
|
||||
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 += fmt.Sprintf("<w:ilvl w:val=\"%d\" />", p.Properties.NumLevel)
|
||||
xml += fmt.Sprintf("<w:numId w:val=\"%d\" />", p.Properties.NumID)
|
||||
xml += "</w:numPr>"
|
||||
}
|
||||
|
||||
@@ -254,37 +218,78 @@ func (p *Paragraph) ToXML() string {
|
||||
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 + "\" />"
|
||||
xml += fmt.Sprintf("<w:top w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
p.Properties.BorderTop.Style,
|
||||
p.Properties.BorderTop.Size,
|
||||
p.Properties.BorderTop.Space,
|
||||
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 + "\" />"
|
||||
xml += fmt.Sprintf("<w:bottom w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
p.Properties.BorderBottom.Style,
|
||||
p.Properties.BorderBottom.Size,
|
||||
p.Properties.BorderBottom.Space,
|
||||
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 + "\" />"
|
||||
xml += fmt.Sprintf("<w:left w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
p.Properties.BorderLeft.Style,
|
||||
p.Properties.BorderLeft.Size,
|
||||
p.Properties.BorderLeft.Space,
|
||||
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 += fmt.Sprintf("<w:right w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
p.Properties.BorderRight.Style,
|
||||
p.Properties.BorderRight.Size,
|
||||
p.Properties.BorderRight.Space,
|
||||
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 += fmt.Sprintf("<w:shd w:val=\"%s\" w:fill=\"%s\" w:color=\"%s\" />",
|
||||
p.Properties.Shading.Pattern,
|
||||
p.Properties.Shading.Fill,
|
||||
p.Properties.Shading.Color)
|
||||
}
|
||||
|
||||
// 间距
|
||||
if p.Properties.SpacingBefore > 0 || p.Properties.SpacingAfter > 0 || p.Properties.SpacingLine > 0 {
|
||||
xml += "<w:spacing"
|
||||
if p.Properties.SpacingBefore > 0 {
|
||||
xml += fmt.Sprintf(" w:before=\"%d\"", p.Properties.SpacingBefore)
|
||||
}
|
||||
if p.Properties.SpacingAfter > 0 {
|
||||
xml += fmt.Sprintf(" w:after=\"%d\"", p.Properties.SpacingAfter)
|
||||
}
|
||||
if p.Properties.SpacingLine > 0 {
|
||||
xml += fmt.Sprintf(" w:line=\"%d\"", p.Properties.SpacingLine)
|
||||
xml += fmt.Sprintf(" w:lineRule=\"%s\"", p.Properties.SpacingLineRule)
|
||||
}
|
||||
xml += " />"
|
||||
}
|
||||
|
||||
// 缩进
|
||||
if p.Properties.IndentLeft > 0 || p.Properties.IndentRight > 0 || p.Properties.IndentFirstLine > 0 {
|
||||
xml += "<w:ind"
|
||||
if p.Properties.IndentLeft > 0 {
|
||||
xml += fmt.Sprintf(" w:left=\"%d\"", p.Properties.IndentLeft)
|
||||
}
|
||||
if p.Properties.IndentRight > 0 {
|
||||
xml += fmt.Sprintf(" w:right=\"%d\"", p.Properties.IndentRight)
|
||||
}
|
||||
if p.Properties.IndentFirstLine > 0 {
|
||||
xml += fmt.Sprintf(" w:firstLine=\"%d\"", p.Properties.IndentFirstLine)
|
||||
}
|
||||
xml += " />"
|
||||
}
|
||||
|
||||
// 对齐方式
|
||||
if p.Properties.Alignment != "" {
|
||||
xml += fmt.Sprintf("<w:jc w:val=\"%s\" />", p.Properties.Alignment)
|
||||
}
|
||||
|
||||
xml += "</w:pPr>"
|
||||
|
127
document/run.go
127
document/run.go
@@ -206,115 +206,130 @@ func (r *Run) AddPageNumber() *Run {
|
||||
return r.AddField("begin", " PAGE ")
|
||||
}
|
||||
|
||||
// ToXML 将文本运行转换为XML
|
||||
// ToXML 将Run转换为XML
|
||||
func (r *Run) ToXML() string {
|
||||
xml := "<w:r>"
|
||||
|
||||
// 添加文本运行属性
|
||||
// 添加运行属性 - 严格按照Word XML规范顺序
|
||||
xml += "<w:rPr>"
|
||||
|
||||
// 字体
|
||||
// 运行样式(缺失,预留位置)
|
||||
|
||||
// 1. 字体
|
||||
if r.Properties.FontFamily != "" {
|
||||
xml += "<w:rFonts w:ascii=\"" + r.Properties.FontFamily + "\""
|
||||
xml += " w:eastAsia=\"" + r.Properties.FontFamily + "\""
|
||||
xml += " w:hAnsi=\"" + r.Properties.FontFamily + "\""
|
||||
xml += " w:cs=\"" + r.Properties.FontFamily + "\" />"
|
||||
xml += fmt.Sprintf("<w:rFonts w:ascii=\"%s\" w:hAnsi=\"%s\" w:eastAsia=\"%s\" w:cs=\"%s\" />",
|
||||
r.Properties.FontFamily,
|
||||
r.Properties.FontFamily,
|
||||
r.Properties.FontFamily,
|
||||
r.Properties.FontFamily)
|
||||
}
|
||||
|
||||
// 字号
|
||||
if r.Properties.FontSize > 0 {
|
||||
xml += "<w:sz w:val=\"" + fmt.Sprintf("%d", r.Properties.FontSize) + "\" />"
|
||||
xml += "<w:szCs w:val=\"" + fmt.Sprintf("%d", r.Properties.FontSize) + "\" />"
|
||||
}
|
||||
|
||||
// 颜色
|
||||
if r.Properties.Color != "" {
|
||||
xml += "<w:color w:val=\"" + r.Properties.Color + "\" />"
|
||||
}
|
||||
|
||||
// 粗体
|
||||
// 2. 加粗
|
||||
if r.Properties.Bold {
|
||||
xml += "<w:b />"
|
||||
// 3. 复杂文本加粗
|
||||
xml += "<w:bCs />"
|
||||
}
|
||||
|
||||
// 斜体
|
||||
// 4. 斜体
|
||||
if r.Properties.Italic {
|
||||
xml += "<w:i />"
|
||||
// 5. 复杂文本斜体
|
||||
xml += "<w:iCs />"
|
||||
}
|
||||
|
||||
// 下划线
|
||||
if r.Properties.Underline != "" {
|
||||
xml += "<w:u w:val=\"" + r.Properties.Underline + "\" />"
|
||||
}
|
||||
|
||||
// 删除线
|
||||
if r.Properties.Strike {
|
||||
xml += "<w:strike />"
|
||||
}
|
||||
|
||||
// 双删除线
|
||||
if r.Properties.DoubleStrike {
|
||||
xml += "<w:dstrike />"
|
||||
}
|
||||
|
||||
// 突出显示颜色
|
||||
if r.Properties.Highlight != "" {
|
||||
xml += "<w:highlight w:val=\"" + r.Properties.Highlight + "\" />"
|
||||
}
|
||||
|
||||
// 全部大写
|
||||
// 6. 全部大写
|
||||
if r.Properties.Caps {
|
||||
xml += "<w:caps />"
|
||||
}
|
||||
|
||||
// 小型大写
|
||||
// 7. 小型大写
|
||||
if r.Properties.SmallCaps {
|
||||
xml += "<w:smallCaps />"
|
||||
}
|
||||
|
||||
// 字符间距
|
||||
// 8. 删除线
|
||||
if r.Properties.Strike {
|
||||
xml += "<w:strike />"
|
||||
}
|
||||
|
||||
// 9. 双删除线
|
||||
if r.Properties.DoubleStrike {
|
||||
xml += "<w:dstrike />"
|
||||
}
|
||||
|
||||
// 10-18. 其他格式(outline, shadow, emboss等,缺失,预留位置)
|
||||
|
||||
// 19. 颜色
|
||||
if r.Properties.Color != "" {
|
||||
xml += fmt.Sprintf("<w:color w:val=\"%s\" />", r.Properties.Color)
|
||||
}
|
||||
|
||||
// 20. 字符间距
|
||||
if r.Properties.CharacterSpacing != 0 {
|
||||
xml += "<w:spacing w:val=\"" + fmt.Sprintf("%d", r.Properties.CharacterSpacing) + "\" />"
|
||||
xml += fmt.Sprintf("<w:spacing w:val=\"%d\" />", r.Properties.CharacterSpacing)
|
||||
}
|
||||
|
||||
// 底纹
|
||||
if r.Properties.Shading != nil {
|
||||
xml += "<w:shd w:val=\"" + r.Properties.Shading.Pattern + "\""
|
||||
xml += " w:fill=\"" + r.Properties.Shading.Fill + "\""
|
||||
xml += " w:color=\"" + r.Properties.Shading.Color + "\" />"
|
||||
// 21-23. 其他属性(缺失,预留位置)
|
||||
|
||||
// 24. 字号
|
||||
if r.Properties.FontSize > 0 {
|
||||
xml += fmt.Sprintf("<w:sz w:val=\"%d\" />", r.Properties.FontSize)
|
||||
// 25. 复杂文本字号
|
||||
xml += fmt.Sprintf("<w:szCs w:val=\"%d\" />", r.Properties.FontSize)
|
||||
}
|
||||
|
||||
// 上标/下标
|
||||
// 26. 突出显示
|
||||
if r.Properties.Highlight != "" {
|
||||
xml += fmt.Sprintf("<w:highlight w:val=\"%s\" />", r.Properties.Highlight)
|
||||
}
|
||||
|
||||
// 27. 下划线
|
||||
if r.Properties.Underline != "" {
|
||||
xml += fmt.Sprintf("<w:u w:val=\"%s\" />", r.Properties.Underline)
|
||||
}
|
||||
|
||||
// 28-31. 其他属性(缺失,预留位置)
|
||||
|
||||
// 32. 上标/下标
|
||||
if r.Properties.Superscript {
|
||||
xml += "<w:vertAlign w:val=\"superscript\" />"
|
||||
} else if r.Properties.Subscript {
|
||||
xml += "<w:vertAlign w:val=\"subscript\" />"
|
||||
} else if r.Properties.VertAlign != "" {
|
||||
xml += "<w:vertAlign w:val=\"" + r.Properties.VertAlign + "\" />"
|
||||
xml += fmt.Sprintf("<w:vertAlign w:val=\"%s\" />", r.Properties.VertAlign)
|
||||
}
|
||||
|
||||
// 从右到左文本方向
|
||||
// 33. 从右到左文本方向
|
||||
if r.Properties.RTL {
|
||||
xml += "<w:rtl />"
|
||||
}
|
||||
|
||||
// 语言
|
||||
// 34-35. 其他属性(缺失,预留位置)
|
||||
|
||||
// 36. 语言
|
||||
if r.Properties.Language != "" {
|
||||
xml += "<w:lang w:val=\"" + r.Properties.Language + "\" />"
|
||||
xml += fmt.Sprintf("<w:lang w:val=\"%s\" />", r.Properties.Language)
|
||||
}
|
||||
|
||||
// 底纹(shd应该在位置30)
|
||||
if r.Properties.Shading != nil {
|
||||
xml += fmt.Sprintf("<w:shd w:val=\"%s\" w:fill=\"%s\" w:color=\"%s\" />",
|
||||
r.Properties.Shading.Pattern,
|
||||
r.Properties.Shading.Fill,
|
||||
r.Properties.Shading.Color)
|
||||
}
|
||||
|
||||
xml += "</w:rPr>"
|
||||
|
||||
// 添加分隔符
|
||||
if r.BreakType != "" {
|
||||
xml += "<w:br w:type=\"" + r.BreakType + "\" />"
|
||||
xml += fmt.Sprintf("<w:br w:type=\"%s\" />", r.BreakType)
|
||||
}
|
||||
|
||||
// 添加文本
|
||||
if r.Text != "" {
|
||||
xml += "<w:t xml:space=\"preserve\">" + r.Text + "</w:t>"
|
||||
xml += fmt.Sprintf("<w:t xml:space=\"preserve\">%s</w:t>", r.Text)
|
||||
}
|
||||
|
||||
// 添加图形
|
||||
|
@@ -387,108 +387,105 @@ func (t *Table) ToXML() string {
|
||||
// 添加表格属性
|
||||
xml += "<w:tblPr>"
|
||||
|
||||
// 表格宽度
|
||||
if t.Properties.Width > 0 {
|
||||
xml += "<w:tblW w:w=\"" + fmt.Sprintf("%d", t.Properties.Width) + "\""
|
||||
xml += " w:type=\"" + t.Properties.WidthType + "\" />"
|
||||
} else {
|
||||
xml += "<w:tblW w:w=\"0\" w:type=\"auto\" />"
|
||||
// 表格样式ID
|
||||
if t.Properties.Style != "" {
|
||||
xml += fmt.Sprintf("<w:tblStyle w:val=\"%s\" />", t.Properties.Style)
|
||||
}
|
||||
|
||||
// 表格宽度
|
||||
xml += fmt.Sprintf("<w:tblW w:w=\"%d\" w:type=\"%s\" />", t.Properties.Width, t.Properties.WidthType)
|
||||
|
||||
// 表格对齐方式
|
||||
if t.Properties.Alignment != "" {
|
||||
xml += "<w:jc w:val=\"" + t.Properties.Alignment + "\" />"
|
||||
xml += fmt.Sprintf("<w:jc w:val=\"%s\" />", t.Properties.Alignment)
|
||||
}
|
||||
|
||||
// 表格缩进
|
||||
if t.Properties.Indent > 0 {
|
||||
xml += "<w:tblInd w:w=\"" + fmt.Sprintf("%d", t.Properties.Indent) + "\""
|
||||
xml += " w:type=\"dxa\" />"
|
||||
xml += fmt.Sprintf("<w:tblInd w:w=\"%d\" w:type=\"dxa\" />", t.Properties.Indent)
|
||||
}
|
||||
|
||||
// 表格边框
|
||||
if t.Properties.Borders != nil {
|
||||
xml += "<w:tblBorders>"
|
||||
if t.Properties.Borders.Top != nil {
|
||||
xml += "<w:top w:val=\"" + t.Properties.Borders.Top.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", t.Properties.Borders.Top.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", t.Properties.Borders.Top.Space) + "\""
|
||||
xml += " w:color=\"" + t.Properties.Borders.Top.Color + "\" />"
|
||||
}
|
||||
if t.Properties.Borders.Bottom != nil {
|
||||
xml += "<w:bottom w:val=\"" + t.Properties.Borders.Bottom.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", t.Properties.Borders.Bottom.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", t.Properties.Borders.Bottom.Space) + "\""
|
||||
xml += " w:color=\"" + t.Properties.Borders.Bottom.Color + "\" />"
|
||||
xml += fmt.Sprintf("<w:top w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
t.Properties.Borders.Top.Style,
|
||||
t.Properties.Borders.Top.Size,
|
||||
t.Properties.Borders.Top.Space,
|
||||
t.Properties.Borders.Top.Color)
|
||||
}
|
||||
if t.Properties.Borders.Left != nil {
|
||||
xml += "<w:left w:val=\"" + t.Properties.Borders.Left.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", t.Properties.Borders.Left.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", t.Properties.Borders.Left.Space) + "\""
|
||||
xml += " w:color=\"" + t.Properties.Borders.Left.Color + "\" />"
|
||||
xml += fmt.Sprintf("<w:left w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
t.Properties.Borders.Left.Style,
|
||||
t.Properties.Borders.Left.Size,
|
||||
t.Properties.Borders.Left.Space,
|
||||
t.Properties.Borders.Left.Color)
|
||||
}
|
||||
if t.Properties.Borders.Bottom != nil {
|
||||
xml += fmt.Sprintf("<w:bottom w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
t.Properties.Borders.Bottom.Style,
|
||||
t.Properties.Borders.Bottom.Size,
|
||||
t.Properties.Borders.Bottom.Space,
|
||||
t.Properties.Borders.Bottom.Color)
|
||||
}
|
||||
if t.Properties.Borders.Right != nil {
|
||||
xml += "<w:right w:val=\"" + t.Properties.Borders.Right.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", t.Properties.Borders.Right.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", t.Properties.Borders.Right.Space) + "\""
|
||||
xml += " w:color=\"" + t.Properties.Borders.Right.Color + "\" />"
|
||||
xml += fmt.Sprintf("<w:right w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
t.Properties.Borders.Right.Style,
|
||||
t.Properties.Borders.Right.Size,
|
||||
t.Properties.Borders.Right.Space,
|
||||
t.Properties.Borders.Right.Color)
|
||||
}
|
||||
if t.Properties.Borders.InsideH != nil {
|
||||
xml += "<w:insideH w:val=\"" + t.Properties.Borders.InsideH.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", t.Properties.Borders.InsideH.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", t.Properties.Borders.InsideH.Space) + "\""
|
||||
xml += " w:color=\"" + t.Properties.Borders.InsideH.Color + "\" />"
|
||||
xml += fmt.Sprintf("<w:insideH w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
t.Properties.Borders.InsideH.Style,
|
||||
t.Properties.Borders.InsideH.Size,
|
||||
t.Properties.Borders.InsideH.Space,
|
||||
t.Properties.Borders.InsideH.Color)
|
||||
}
|
||||
if t.Properties.Borders.InsideV != nil {
|
||||
xml += "<w:insideV w:val=\"" + t.Properties.Borders.InsideV.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", t.Properties.Borders.InsideV.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", t.Properties.Borders.InsideV.Space) + "\""
|
||||
xml += " w:color=\"" + t.Properties.Borders.InsideV.Color + "\" />"
|
||||
xml += fmt.Sprintf("<w:insideV w:val=\"%s\" w:sz=\"%d\" w:space=\"%d\" w:color=\"%s\" />",
|
||||
t.Properties.Borders.InsideV.Style,
|
||||
t.Properties.Borders.InsideV.Size,
|
||||
t.Properties.Borders.InsideV.Space,
|
||||
t.Properties.Borders.InsideV.Color)
|
||||
}
|
||||
xml += "</w:tblBorders>"
|
||||
}
|
||||
|
||||
// 表格单元格边距
|
||||
// 表格布局
|
||||
if t.Properties.Layout != "" {
|
||||
xml += fmt.Sprintf("<w:tblLayout w:type=\"%s\" />", t.Properties.Layout)
|
||||
}
|
||||
|
||||
// 单元格边距
|
||||
if t.Properties.CellMargin != nil {
|
||||
xml += "<w:tblCellMar>"
|
||||
if t.Properties.CellMargin.Top > 0 {
|
||||
xml += "<w:top w:w=\"" + fmt.Sprintf("%d", t.Properties.CellMargin.Top) + "\""
|
||||
xml += " w:type=\"dxa\" />"
|
||||
}
|
||||
if t.Properties.CellMargin.Bottom > 0 {
|
||||
xml += "<w:bottom w:w=\"" + fmt.Sprintf("%d", t.Properties.CellMargin.Bottom) + "\""
|
||||
xml += " w:type=\"dxa\" />"
|
||||
xml += fmt.Sprintf("<w:top w:w=\"%d\" w:type=\"dxa\" />", t.Properties.CellMargin.Top)
|
||||
}
|
||||
if t.Properties.CellMargin.Left > 0 {
|
||||
xml += "<w:left w:w=\"" + fmt.Sprintf("%d", t.Properties.CellMargin.Left) + "\""
|
||||
xml += " w:type=\"dxa\" />"
|
||||
xml += fmt.Sprintf("<w:left w:w=\"%d\" w:type=\"dxa\" />", t.Properties.CellMargin.Left)
|
||||
}
|
||||
if t.Properties.CellMargin.Bottom > 0 {
|
||||
xml += fmt.Sprintf("<w:bottom w:w=\"%d\" w:type=\"dxa\" />", t.Properties.CellMargin.Bottom)
|
||||
}
|
||||
if t.Properties.CellMargin.Right > 0 {
|
||||
xml += "<w:right w:w=\"" + fmt.Sprintf("%d", t.Properties.CellMargin.Right) + "\""
|
||||
xml += " w:type=\"dxa\" />"
|
||||
xml += fmt.Sprintf("<w:right w:w=\"%d\" w:type=\"dxa\" />", t.Properties.CellMargin.Right)
|
||||
}
|
||||
xml += "</w:tblCellMar>"
|
||||
}
|
||||
|
||||
// 表格布局方式
|
||||
if t.Properties.Layout != "" {
|
||||
xml += "<w:tblLayout w:type=\"" + t.Properties.Layout + "\" />"
|
||||
}
|
||||
|
||||
// 表格样式
|
||||
if t.Properties.Style != "" {
|
||||
xml += "<w:tblStyle w:val=\"" + t.Properties.Style + "\" />"
|
||||
}
|
||||
|
||||
// 表格外观
|
||||
if t.Properties.Look != "" {
|
||||
xml += "<w:tblLook w:val=\"" + t.Properties.Look + "\""
|
||||
xml += " w:firstRow=\"" + fmt.Sprintf("%d", boolToInt(t.Properties.FirstRow)) + "\""
|
||||
xml += " w:lastRow=\"" + fmt.Sprintf("%d", boolToInt(t.Properties.LastRow)) + "\""
|
||||
xml += " w:firstColumn=\"" + fmt.Sprintf("%d", boolToInt(t.Properties.FirstColumn)) + "\""
|
||||
xml += " w:lastColumn=\"" + fmt.Sprintf("%d", boolToInt(t.Properties.LastColumn)) + "\""
|
||||
xml += " w:noHBand=\"" + fmt.Sprintf("%d", boolToInt(t.Properties.NoHBand)) + "\""
|
||||
xml += " w:noVBand=\"" + fmt.Sprintf("%d", boolToInt(t.Properties.NoVBand)) + "\" />"
|
||||
xml += fmt.Sprintf("<w:tblLook w:val=\"%s\" w:firstRow=\"%v\" w:lastRow=\"%v\" w:firstColumn=\"%v\" w:lastColumn=\"%v\" w:noHBand=\"%v\" w:noVBand=\"%v\" />",
|
||||
t.Properties.Look,
|
||||
formatBoolToWXml(t.Properties.FirstRow),
|
||||
formatBoolToWXml(t.Properties.LastRow),
|
||||
formatBoolToWXml(t.Properties.FirstColumn),
|
||||
formatBoolToWXml(t.Properties.LastColumn),
|
||||
formatBoolToWXml(t.Properties.NoHBand),
|
||||
formatBoolToWXml(t.Properties.NoVBand))
|
||||
}
|
||||
|
||||
xml += "</w:tblPr>"
|
||||
@@ -504,129 +501,133 @@ func (t *Table) ToXML() string {
|
||||
|
||||
// 添加所有行的XML
|
||||
for _, row := range t.Rows {
|
||||
xml += "<w:tr>"
|
||||
|
||||
// 添加行属性
|
||||
xml += "<w:trPr>"
|
||||
|
||||
// 行高
|
||||
if row.Properties.Height > 0 {
|
||||
xml += "<w:trHeight w:val=\"" + fmt.Sprintf("%d", row.Properties.Height) + "\""
|
||||
xml += " w:hRule=\"" + row.Properties.HeightRule + "\" />"
|
||||
}
|
||||
|
||||
// 不允许跨页分割
|
||||
if row.Properties.CantSplit {
|
||||
xml += "<w:cantSplit />"
|
||||
}
|
||||
|
||||
// 表头行
|
||||
if row.Properties.IsHeader {
|
||||
xml += "<w:tblHeader />"
|
||||
}
|
||||
|
||||
xml += "</w:trPr>"
|
||||
|
||||
// 添加所有单元格的XML
|
||||
for _, cell := range row.Cells {
|
||||
xml += "<w:tc>"
|
||||
|
||||
// 添加单元格属性
|
||||
xml += "<w:tcPr>"
|
||||
|
||||
// 单元格宽度
|
||||
if cell.Properties.Width > 0 {
|
||||
xml += "<w:tcW w:w=\"" + fmt.Sprintf("%d", cell.Properties.Width) + "\""
|
||||
xml += " w:type=\"" + cell.Properties.WidthType + "\" />"
|
||||
} else {
|
||||
xml += "<w:tcW w:w=\"0\" w:type=\"auto\" />"
|
||||
}
|
||||
|
||||
// 垂直对齐方式
|
||||
if cell.Properties.VertAlign != "" {
|
||||
xml += "<w:vAlign w:val=\"" + cell.Properties.VertAlign + "\" />"
|
||||
}
|
||||
|
||||
// 单元格边框
|
||||
if cell.Properties.Borders != nil {
|
||||
xml += "<w:tcBorders>"
|
||||
if cell.Properties.Borders.Top != nil {
|
||||
xml += "<w:top w:val=\"" + cell.Properties.Borders.Top.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", cell.Properties.Borders.Top.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", cell.Properties.Borders.Top.Space) + "\""
|
||||
xml += " w:color=\"" + cell.Properties.Borders.Top.Color + "\" />"
|
||||
}
|
||||
if cell.Properties.Borders.Bottom != nil {
|
||||
xml += "<w:bottom w:val=\"" + cell.Properties.Borders.Bottom.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", cell.Properties.Borders.Bottom.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", cell.Properties.Borders.Bottom.Space) + "\""
|
||||
xml += " w:color=\"" + cell.Properties.Borders.Bottom.Color + "\" />"
|
||||
}
|
||||
if cell.Properties.Borders.Left != nil {
|
||||
xml += "<w:left w:val=\"" + cell.Properties.Borders.Left.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", cell.Properties.Borders.Left.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", cell.Properties.Borders.Left.Space) + "\""
|
||||
xml += " w:color=\"" + cell.Properties.Borders.Left.Color + "\" />"
|
||||
}
|
||||
if cell.Properties.Borders.Right != nil {
|
||||
xml += "<w:right w:val=\"" + cell.Properties.Borders.Right.Style + "\""
|
||||
xml += " w:sz=\"" + fmt.Sprintf("%d", cell.Properties.Borders.Right.Size) + "\""
|
||||
xml += " w:space=\"" + fmt.Sprintf("%d", cell.Properties.Borders.Right.Space) + "\""
|
||||
xml += " w:color=\"" + cell.Properties.Borders.Right.Color + "\" />"
|
||||
}
|
||||
xml += "</w:tcBorders>"
|
||||
}
|
||||
|
||||
// 底纹
|
||||
if cell.Properties.Shading != nil {
|
||||
xml += "<w:shd w:val=\"" + cell.Properties.Shading.Pattern + "\""
|
||||
xml += " w:fill=\"" + cell.Properties.Shading.Fill + "\""
|
||||
xml += " w:color=\"" + cell.Properties.Shading.Color + "\" />"
|
||||
}
|
||||
|
||||
// 跨列数
|
||||
if cell.Properties.GridSpan > 1 {
|
||||
xml += "<w:gridSpan w:val=\"" + fmt.Sprintf("%d", cell.Properties.GridSpan) + "\" />"
|
||||
}
|
||||
|
||||
// 垂直合并
|
||||
if cell.Properties.VMerge != "" {
|
||||
xml += "<w:vMerge w:val=\"" + cell.Properties.VMerge + "\" />"
|
||||
}
|
||||
|
||||
// 不换行
|
||||
if cell.Properties.NoWrap {
|
||||
xml += "<w:noWrap />"
|
||||
}
|
||||
|
||||
// 适应文本
|
||||
if cell.Properties.FitText {
|
||||
xml += "<w:fitText />"
|
||||
}
|
||||
|
||||
xml += "</w:tcPr>"
|
||||
|
||||
// 添加所有内容元素的XML
|
||||
for _, content := range cell.Content {
|
||||
switch v := content.(type) {
|
||||
case *Paragraph:
|
||||
xml += v.ToXML()
|
||||
case *Table:
|
||||
xml += v.ToXML()
|
||||
}
|
||||
}
|
||||
|
||||
// 如果单元格没有内容,添加一个空段落
|
||||
if len(cell.Content) == 0 {
|
||||
xml += "<w:p><w:pPr></w:pPr></w:p>"
|
||||
}
|
||||
|
||||
xml += "</w:tc>"
|
||||
}
|
||||
|
||||
xml += "</w:tr>"
|
||||
xml += row.ToXML()
|
||||
}
|
||||
|
||||
xml += "</w:tbl>"
|
||||
return xml
|
||||
}
|
||||
|
||||
// formatBoolToWXml 将布尔值转换为Word XML中使用的字符串表示
|
||||
func formatBoolToWXml(value bool) string {
|
||||
if value {
|
||||
return "1"
|
||||
}
|
||||
return "0"
|
||||
}
|
||||
|
||||
// ToXML 将表格行转换为XML
|
||||
func (r *TableRow) ToXML() string {
|
||||
xml := "<w:tr>"
|
||||
|
||||
// 添加行属性
|
||||
xml += "<w:trPr>"
|
||||
|
||||
// 行高
|
||||
if r.Properties.Height > 0 {
|
||||
xml += "<w:trHeight w:val=\"" + fmt.Sprintf("%d", r.Properties.Height) + "\" w:hRule=\"" + r.Properties.HeightRule + "\" />"
|
||||
}
|
||||
|
||||
// 不允许跨页分割
|
||||
if r.Properties.CantSplit {
|
||||
xml += "<w:cantSplit />"
|
||||
}
|
||||
|
||||
// 表头行
|
||||
if r.Properties.IsHeader {
|
||||
xml += "<w:tblHeader />"
|
||||
}
|
||||
|
||||
xml += "</w:trPr>"
|
||||
|
||||
// 添加所有单元格的XML
|
||||
for _, cell := range r.Cells {
|
||||
xml += cell.ToXML()
|
||||
}
|
||||
|
||||
xml += "</w:tr>"
|
||||
return xml
|
||||
}
|
||||
|
||||
// ToXML 将表格单元格转换为XML
|
||||
func (c *TableCell) ToXML() string {
|
||||
xml := "<w:tc>"
|
||||
|
||||
// 添加单元格属性
|
||||
xml += "<w:tcPr>"
|
||||
|
||||
// 单元格宽度
|
||||
if c.Properties.Width > 0 {
|
||||
xml += "<w:tcW w:w=\"" + fmt.Sprintf("%d", c.Properties.Width) + "\" w:type=\"" + c.Properties.WidthType + "\" />"
|
||||
} else {
|
||||
xml += "<w:tcW w:w=\"0\" w:type=\"auto\" />"
|
||||
}
|
||||
|
||||
// 垂直对齐方式
|
||||
if c.Properties.VertAlign != "" {
|
||||
xml += "<w:vAlign w:val=\"" + c.Properties.VertAlign + "\" />"
|
||||
}
|
||||
|
||||
// 单元格边框
|
||||
if c.Properties.Borders != nil {
|
||||
xml += "<w:tcBorders>"
|
||||
if c.Properties.Borders.Top != nil {
|
||||
xml += "<w:top w:val=\"" + c.Properties.Borders.Top.Style + "\" w:sz=\"" + fmt.Sprintf("%d", c.Properties.Borders.Top.Size) + "\" w:space=\"" + fmt.Sprintf("%d", c.Properties.Borders.Top.Space) + "\" w:color=\"" + c.Properties.Borders.Top.Color + "\" />"
|
||||
}
|
||||
if c.Properties.Borders.Bottom != nil {
|
||||
xml += "<w:bottom w:val=\"" + c.Properties.Borders.Bottom.Style + "\" w:sz=\"" + fmt.Sprintf("%d", c.Properties.Borders.Bottom.Size) + "\" w:space=\"" + fmt.Sprintf("%d", c.Properties.Borders.Bottom.Space) + "\" w:color=\"" + c.Properties.Borders.Bottom.Color + "\" />"
|
||||
}
|
||||
if c.Properties.Borders.Left != nil {
|
||||
xml += "<w:left w:val=\"" + c.Properties.Borders.Left.Style + "\" w:sz=\"" + fmt.Sprintf("%d", c.Properties.Borders.Left.Size) + "\" w:space=\"" + fmt.Sprintf("%d", c.Properties.Borders.Left.Space) + "\" w:color=\"" + c.Properties.Borders.Left.Color + "\" />"
|
||||
}
|
||||
if c.Properties.Borders.Right != nil {
|
||||
xml += "<w:right w:val=\"" + c.Properties.Borders.Right.Style + "\" w:sz=\"" + fmt.Sprintf("%d", c.Properties.Borders.Right.Size) + "\" w:space=\"" + fmt.Sprintf("%d", c.Properties.Borders.Right.Space) + "\" w:color=\"" + c.Properties.Borders.Right.Color + "\" />"
|
||||
}
|
||||
xml += "</w:tcBorders>"
|
||||
}
|
||||
|
||||
// 底纹
|
||||
if c.Properties.Shading != nil {
|
||||
xml += "<w:shd w:val=\"" + c.Properties.Shading.Pattern + "\" w:fill=\"" + c.Properties.Shading.Fill + "\" w:color=\"" + c.Properties.Shading.Color + "\" />"
|
||||
}
|
||||
|
||||
// 跨列数
|
||||
if c.Properties.GridSpan > 1 {
|
||||
xml += "<w:gridSpan w:val=\"" + fmt.Sprintf("%d", c.Properties.GridSpan) + "\" />"
|
||||
}
|
||||
|
||||
// 垂直合并
|
||||
if c.Properties.VMerge != "" {
|
||||
xml += "<w:vMerge w:val=\"" + c.Properties.VMerge + "\" />"
|
||||
}
|
||||
|
||||
// 不换行
|
||||
if c.Properties.NoWrap {
|
||||
xml += "<w:noWrap />"
|
||||
}
|
||||
|
||||
// 适应文本
|
||||
if c.Properties.FitText {
|
||||
xml += "<w:fitText />"
|
||||
}
|
||||
|
||||
xml += "</w:tcPr>"
|
||||
|
||||
// 添加所有内容元素的XML
|
||||
for _, content := range c.Content {
|
||||
switch v := content.(type) {
|
||||
case *Paragraph:
|
||||
xml += v.ToXML()
|
||||
case *Table:
|
||||
xml += v.ToXML()
|
||||
}
|
||||
}
|
||||
|
||||
// 如果单元格没有内容,添加一个空段落
|
||||
if len(c.Content) == 0 {
|
||||
xml += "<w:p><w:pPr></w:pPr></w:p>"
|
||||
}
|
||||
|
||||
xml += "</w:tc>"
|
||||
return xml
|
||||
}
|
||||
|
@@ -40,7 +40,6 @@ func NewContentTypes() *ContentTypes {
|
||||
ct.AddOverride("/xl/workbook.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml")
|
||||
ct.AddOverride("/xl/styles.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml")
|
||||
ct.AddOverride("/xl/theme/theme1.xml", "application/vnd.openxmlformats-officedocument.theme+xml")
|
||||
ct.AddOverride("/xl/worksheets/sheet1.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml")
|
||||
ct.AddOverride("/xl/sharedStrings.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml")
|
||||
|
||||
return ct
|
||||
|
@@ -259,7 +259,7 @@ func main() {
|
||||
})
|
||||
|
||||
// 保存Excel文件
|
||||
err := wb.Save("sales_report.xlsx")
|
||||
err := wb.Save("./workbook/examples/simple/sales_report.xlsx")
|
||||
if err != nil {
|
||||
fmt.Println("保存Excel文件时出错:", err)
|
||||
return
|
||||
|
@@ -71,6 +71,11 @@ func (wb *Workbook) Save(filename string) error {
|
||||
zipWriter := zip.NewWriter(file)
|
||||
defer zipWriter.Close()
|
||||
|
||||
// 为每个工作表添加内容类型覆盖
|
||||
for i := range wb.Worksheets {
|
||||
wb.ContentTypes.AddWorksheetOverride(i + 1)
|
||||
}
|
||||
|
||||
// 添加[Content_Types].xml
|
||||
contentTypesWriter, err := zipWriter.Create("[Content_Types].xml")
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user