diff --git a/README.md b/README.md
index cdc722e..e34718d 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,11 @@
-# WordZero - Golang Word Document Library
+
+

+
+
WordZero - Golang Word Document Library
+
+
+
[](https://golang.org)
[](LICENSE)
[](#testing)
@@ -7,6 +13,8 @@
[](https://github.com/ZeroHawkeye/wordZero/wiki/en-Performance-Benchmarks)
[](https://deepwiki.com/ZeroHawkeye/wordZero)
+
+
**English** | [中文](README_zh.md)
## Project Introduction
@@ -288,11 +296,29 @@ wordZero/
├── examples/ # Usage examples
├── test/ # Integration tests
├── benchmark/ # Performance benchmarks
+├── docs/ # Documentation and assets
+│ ├── logo.svg # Main logo with performance indicators
+│ ├── logo-banner.svg # Banner version for README headers
+│ └── logo-simple.svg # Simplified icon version
└── wordZero.wiki/ # Complete documentation
```
👉 **View detailed structure description**: [Project Structure](https://github.com/ZeroHawkeye/wordZero/wiki/en-Project-Structure)
+### Logo and Branding
+
+The project includes multiple logo variations for different use cases:
+
+
+
+| Logo Type | Usage | Preview |
+|-----------|-------|---------|
+| **Banner** | README headers, documentation |

|
+| **Main** | General branding |

|
+| **Simple** | Icons, favicons |

|
+
+
+
## Contributing
Issues and Pull Requests are welcome! Please ensure before submitting code:
diff --git a/README_zh.md b/README_zh.md
index 9e257d5..3b74b45 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -1,5 +1,11 @@
-# WordZero - Golang Word操作库
+
+

+
+
WordZero - Golang Word操作库
+
+
+
[](https://golang.org)
[](LICENSE)
[](#测试)
@@ -7,6 +13,8 @@
[](https://github.com/ZeroHawkeye/wordZero/wiki/13-%E6%80%A7%E8%83%BD%E5%9F%BA%E5%87%86%E6%B5%8B%E8%AF%95)
[](https://deepwiki.com/ZeroHawkeye/wordZero)
+
+
[English](README.md) | **中文**
## 项目介绍
@@ -288,11 +296,29 @@ wordZero/
├── examples/ # 使用示例
├── test/ # 集成测试
├── benchmark/ # 性能基准测试
+├── docs/ # 文档和资源文件
+│ ├── logo.svg # 主Logo带性能指标
+│ ├── logo-banner.svg # 横幅版本用于README标题
+│ └── logo-simple.svg # 简化图标版本
└── wordZero.wiki/ # 完整文档
```
👉 **查看详细结构说明**: [项目结构详解](https://github.com/ZeroHawkeye/wordZero/wiki/15-项目结构详解)
+### Logo设计
+
+项目包含多种Logo变体,适用于不同使用场景:
+
+
+
+| Logo类型 | 使用场景 | 预览 |
+|----------|----------|------|
+| **横幅版** | README标题、文档头部 |

|
+| **主版本** | 通用品牌展示 |

|
+| **简化版** | 图标、网站标识 |

|
+
+
+
## 贡献指南
欢迎提交 Issue 和 Pull Request!在提交代码前请确保:
diff --git a/docs/logo-banner.svg b/docs/logo-banner.svg
new file mode 100644
index 0000000..6132a6d
--- /dev/null
+++ b/docs/logo-banner.svg
@@ -0,0 +1,99 @@
+
+
\ No newline at end of file
diff --git a/docs/logo-simple.svg b/docs/logo-simple.svg
new file mode 100644
index 0000000..d4a08df
--- /dev/null
+++ b/docs/logo-simple.svg
@@ -0,0 +1,43 @@
+
+
\ No newline at end of file
diff --git a/docs/logo.svg b/docs/logo.svg
new file mode 100644
index 0000000..734a46d
--- /dev/null
+++ b/docs/logo.svg
@@ -0,0 +1,86 @@
+
+
\ No newline at end of file
diff --git a/pkg/document/doc.go b/pkg/document/doc.go
index 44ef440..da5ccdb 100644
--- a/pkg/document/doc.go
+++ b/pkg/document/doc.go
@@ -183,6 +183,7 @@ WordZero 专注于现代的 Office Open XML (OOXML) 格式(.docx 文件),
if err != nil {
var docErr *document.DocumentError
if errors.As(err, &docErr) {
+ Errorf("文档操作失败 - 操作: %s, 错误: %v", docErr.Operation, docErr.Cause)
fmt.Printf("操作: %s, 错误: %v\n", docErr.Operation, docErr.Cause)
}
}
diff --git a/pkg/document/document.go b/pkg/document/document.go
index 451ba25..d6abb25 100644
--- a/pkg/document/document.go
+++ b/pkg/document/document.go
@@ -101,11 +101,11 @@ type ParagraphProperties struct {
XMLName xml.Name `xml:"w:pPr"`
ParagraphStyle *ParagraphStyle `xml:"w:pStyle,omitempty"`
NumberingProperties *NumberingProperties `xml:"w:numPr,omitempty"`
- Spacing *Spacing `xml:"w:spacing,omitempty"`
- Justification *Justification `xml:"w:jc,omitempty"`
- Indentation *Indentation `xml:"w:ind,omitempty"`
- Tabs *Tabs `xml:"w:tabs,omitempty"`
ParagraphBorder *ParagraphBorder `xml:"w:pBdr,omitempty"`
+ Tabs *Tabs `xml:"w:tabs,omitempty"`
+ Spacing *Spacing `xml:"w:spacing,omitempty"`
+ Indentation *Indentation `xml:"w:ind,omitempty"`
+ Justification *Justification `xml:"w:jc,omitempty"`
}
// ParagraphBorder 段落边框
@@ -151,19 +151,20 @@ type Run struct {
}
// RunProperties 文本属性
+// 注意:字段顺序必须符合OpenXML标准,w:rFonts必须在w:color之前
type RunProperties struct {
XMLName xml.Name `xml:"w:rPr"`
+ FontFamily *FontFamily `xml:"w:rFonts,omitempty"`
Bold *Bold `xml:"w:b,omitempty"`
BoldCs *BoldCs `xml:"w:bCs,omitempty"`
Italic *Italic `xml:"w:i,omitempty"`
ItalicCs *ItalicCs `xml:"w:iCs,omitempty"`
Underline *Underline `xml:"w:u,omitempty"`
Strike *Strike `xml:"w:strike,omitempty"`
+ Color *Color `xml:"w:color,omitempty"`
FontSize *FontSize `xml:"w:sz,omitempty"`
FontSizeCs *FontSizeCs `xml:"w:szCs,omitempty"`
- Color *Color `xml:"w:color,omitempty"`
Highlight *Highlight `xml:"w:highlight,omitempty"`
- FontFamily *FontFamily `xml:"w:rFonts,omitempty"`
}
// Bold 粗体
@@ -600,6 +601,10 @@ func (d *Document) AddFormattedParagraph(text string, format *TextFormat) *Parag
runProps := &RunProperties{}
if format != nil {
+ if format.FontFamily != "" {
+ runProps.FontFamily = &FontFamily{ASCII: format.FontFamily}
+ }
+
if format.Bold {
runProps.Bold = &Bold{}
}
@@ -608,19 +613,15 @@ func (d *Document) AddFormattedParagraph(text string, format *TextFormat) *Parag
runProps.Italic = &Italic{}
}
- if format.FontSize > 0 {
- // Word中字体大小是半磅为单位,所以需要乘以2
- runProps.FontSize = &FontSize{Val: strconv.Itoa(format.FontSize * 2)}
- }
-
if format.FontColor != "" {
// 确保颜色格式正确(移除#前缀)
color := strings.TrimPrefix(format.FontColor, "#")
runProps.Color = &Color{Val: color}
}
- if format.FontFamily != "" {
- runProps.FontFamily = &FontFamily{ASCII: format.FontFamily}
+ if format.FontSize > 0 {
+ // Word中字体大小是半磅为单位,所以需要乘以2
+ runProps.FontSize = &FontSize{Val: strconv.Itoa(format.FontSize * 2)}
}
}
@@ -762,6 +763,10 @@ func (p *Paragraph) AddFormattedText(text string, format *TextFormat) {
runProps := &RunProperties{}
if format != nil {
+ if format.FontFamily != "" {
+ runProps.FontFamily = &FontFamily{ASCII: format.FontFamily}
+ }
+
if format.Bold {
runProps.Bold = &Bold{}
}
@@ -770,17 +775,13 @@ func (p *Paragraph) AddFormattedText(text string, format *TextFormat) {
runProps.Italic = &Italic{}
}
- if format.FontSize > 0 {
- runProps.FontSize = &FontSize{Val: strconv.Itoa(format.FontSize * 2)}
- }
-
if format.FontColor != "" {
color := strings.TrimPrefix(format.FontColor, "#")
runProps.Color = &Color{Val: color}
}
- if format.FontFamily != "" {
- runProps.FontFamily = &FontFamily{ASCII: format.FontFamily}
+ if format.FontSize > 0 {
+ runProps.FontSize = &FontSize{Val: strconv.Itoa(format.FontSize * 2)}
}
}
diff --git a/pkg/document/footnotes.go b/pkg/document/footnotes.go
index 1d36d30..2a8f868 100644
--- a/pkg/document/footnotes.go
+++ b/pkg/document/footnotes.go
@@ -788,7 +788,7 @@ func (d *Document) addSettingsRelationship() {
relationship := Relationship{
ID: relationshipID,
Type: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
- Target: "settings.xml",
+ Target: "word/settings.xml",
}
d.relationships.Relationships = append(d.relationships.Relationships, relationship)
}
diff --git a/pkg/document/image.go b/pkg/document/image.go
index bd8e289..73f0c1c 100644
--- a/pkg/document/image.go
+++ b/pkg/document/image.go
@@ -296,8 +296,9 @@ type PicElement struct {
// NvPicPr 非可视图片属性
type NvPicPr struct {
- XMLName xml.Name `xml:"pic:nvPicPr"`
- CNvPr *CNvPr `xml:"pic:cNvPr"`
+ XMLName xml.Name `xml:"pic:nvPicPr"`
+ CNvPr *CNvPr `xml:"pic:cNvPr"`
+ CNvPicPr *CNvPicPr `xml:"pic:cNvPicPr"`
}
// CNvPr 通用非可视属性
@@ -309,6 +310,19 @@ type CNvPr struct {
Title string `xml:"title,attr,omitempty"`
}
+// CNvPicPr 图片特定非可视属性
+type CNvPicPr struct {
+ XMLName xml.Name `xml:"pic:cNvPicPr"`
+ PicLocks *PicLocks `xml:"a:picLocks,omitempty"`
+}
+
+// PicLocks 图片锁定属性
+type PicLocks struct {
+ XMLName xml.Name `xml:"a:picLocks"`
+ NoChangeAspect string `xml:"noChangeAspect,attr,omitempty"`
+ NoChangeArrowheads string `xml:"noChangeArrowheads,attr,omitempty"`
+}
+
// BlipFill 图片填充
type BlipFill struct {
XMLName xml.Name `xml:"pic:blipFill"`
@@ -375,25 +389,31 @@ type AvLst struct {
// AddImageFromFile 从文件添加图片到文档
func (d *Document) AddImageFromFile(filePath string, config *ImageConfig) (*ImageInfo, error) {
+ Debugf("开始添加图片文件: %s", filePath)
+
// 读取图片文件
imageData, err := os.ReadFile(filePath)
if err != nil {
+ Errorf("读取图片文件失败 %s: %v", filePath, err)
return nil, fmt.Errorf("读取图片文件失败: %v", err)
}
// 检测图片格式
format, err := detectImageFormat(imageData)
if err != nil {
+ Errorf("检测图片格式失败 %s: %v", filePath, err)
return nil, fmt.Errorf("检测图片格式失败: %v", err)
}
// 获取图片尺寸
width, height, err := getImageDimensions(imageData, format)
if err != nil {
+ Errorf("获取图片尺寸失败 %s: %v", filePath, err)
return nil, fmt.Errorf("获取图片尺寸失败: %v", err)
}
fileName := filepath.Base(filePath)
+ Infof("成功读取图片: %s (格式: %s, 尺寸: %dx%d, 大小: %d字节)", fileName, format, width, height, len(imageData))
return d.AddImageFromData(imageData, fileName, format, width, height, config)
}
@@ -723,6 +743,11 @@ func (d *Document) createImageGraphic(imageInfo *ImageInfo, displayWidth, displa
Descr: altText,
Title: title,
},
+ CNvPicPr: &CNvPicPr{
+ PicLocks: &PicLocks{
+ NoChangeAspect: "1",
+ },
+ },
},
BlipFill: &BlipFill{
Blip: &Blip{
@@ -979,6 +1004,28 @@ func (d *Document) SetImageAlignment(imageInfo *ImageInfo, alignment AlignmentTy
imageInfo.Config = &ImageConfig{}
}
+ // 更新配置
imageInfo.Config.Alignment = alignment
- return nil
+
+ // 查找包含此图片的段落并更新其对齐方式
+ for _, element := range d.Body.Elements {
+ if paragraph, ok := element.(*Paragraph); ok {
+ // 检查段落中是否包含指定的图片
+ for _, run := range paragraph.Runs {
+ if run.Drawing != nil && run.Drawing.Inline != nil {
+ // 检查docPr ID是否匹配
+ if run.Drawing.Inline.DocPr != nil && run.Drawing.Inline.DocPr.ID == imageInfo.ID {
+ // 更新段落对齐方式
+ if paragraph.Properties == nil {
+ paragraph.Properties = &ParagraphProperties{}
+ }
+ paragraph.Properties.Justification = &Justification{Val: string(alignment)}
+ return nil
+ }
+ }
+ }
+ }
+ }
+
+ return fmt.Errorf("找不到包含图片ID %s的段落", imageInfo.ID)
}
diff --git a/pkg/document/table.go b/pkg/document/table.go
index 271bdb2..9abf28b 100644
--- a/pkg/document/table.go
+++ b/pkg/document/table.go
@@ -846,6 +846,12 @@ func (t *Table) SetCellFormattedText(row, col int, text string, format *TextForm
if format != nil {
run.Properties = &RunProperties{}
+ if format.FontFamily != "" {
+ run.Properties.FontFamily = &FontFamily{
+ ASCII: format.FontFamily,
+ }
+ }
+
if format.Bold {
run.Properties.Bold = &Bold{}
}
@@ -854,21 +860,15 @@ func (t *Table) SetCellFormattedText(row, col int, text string, format *TextForm
run.Properties.Italic = &Italic{}
}
- if format.FontSize > 0 {
- run.Properties.FontSize = &FontSize{
- Val: fmt.Sprintf("%d", format.FontSize*2),
- }
- }
-
if format.FontColor != "" {
run.Properties.Color = &Color{
Val: format.FontColor,
}
}
- if format.FontFamily != "" {
- run.Properties.FontFamily = &FontFamily{
- ASCII: format.FontFamily,
+ if format.FontSize > 0 {
+ run.Properties.FontSize = &FontSize{
+ Val: fmt.Sprintf("%d", format.FontSize*2),
}
}
}
@@ -904,6 +904,12 @@ func (t *Table) AddCellFormattedText(row, col int, text string, format *TextForm
if format != nil {
run.Properties = &RunProperties{}
+ if format.FontFamily != "" {
+ run.Properties.FontFamily = &FontFamily{
+ ASCII: format.FontFamily,
+ }
+ }
+
if format.Bold {
run.Properties.Bold = &Bold{}
}
@@ -912,21 +918,15 @@ func (t *Table) AddCellFormattedText(row, col int, text string, format *TextForm
run.Properties.Italic = &Italic{}
}
- if format.FontSize > 0 {
- run.Properties.FontSize = &FontSize{
- Val: fmt.Sprintf("%d", format.FontSize*2),
- }
- }
-
if format.FontColor != "" {
run.Properties.Color = &Color{
Val: format.FontColor,
}
}
- if format.FontFamily != "" {
- run.Properties.FontFamily = &FontFamily{
- ASCII: format.FontFamily,
+ if format.FontSize > 0 {
+ run.Properties.FontSize = &FontSize{
+ Val: fmt.Sprintf("%d", format.FontSize*2),
}
}
}
diff --git a/pkg/document/template_engine.go b/pkg/document/template_engine.go
index d92e38a..cf432ef 100644
--- a/pkg/document/template_engine.go
+++ b/pkg/document/template_engine.go
@@ -2,7 +2,6 @@ package document
import (
"fmt"
- "log"
"regexp"
)
@@ -33,14 +32,14 @@ func (tr *TemplateRenderer) SetLogging(enabled bool) {
// logInfo 记录信息日志
func (tr *TemplateRenderer) logInfo(format string, args ...interface{}) {
if tr.logger.enabled {
- log.Printf("[模板引擎] "+format, args...)
+ Infof("[模板引擎] "+format, args...)
}
}
// logError 记录错误日志
func (tr *TemplateRenderer) logError(format string, args ...interface{}) {
if tr.logger.enabled {
- log.Printf("[模板引擎-错误] "+format, args...)
+ Errorf("[模板引擎] "+format, args...)
}
}
diff --git a/pkg/style/style.go b/pkg/style/style.go
index ecd5c48..975a6d5 100644
--- a/pkg/style/style.go
+++ b/pkg/style/style.go
@@ -56,17 +56,18 @@ type Next struct {
}
// ParagraphProperties 段落样式属性
+// 注意:字段顺序必须符合OpenXML标准
type ParagraphProperties struct {
XMLName xml.Name `xml:"w:pPr"`
- Spacing *Spacing `xml:"w:spacing,omitempty"`
- Justification *Justification `xml:"w:jc,omitempty"`
- Indentation *Indentation `xml:"w:ind,omitempty"`
KeepNext *KeepNext `xml:"w:keepNext,omitempty"`
KeepLines *KeepLines `xml:"w:keepLines,omitempty"`
PageBreak *PageBreak `xml:"w:pageBreakBefore,omitempty"`
- OutlineLevel *OutlineLevel `xml:"w:outlineLvl,omitempty"`
ParagraphBorder *ParagraphBorder `xml:"w:pBdr,omitempty"`
Shading *Shading `xml:"w:shd,omitempty"`
+ Spacing *Spacing `xml:"w:spacing,omitempty"`
+ Indentation *Indentation `xml:"w:ind,omitempty"`
+ Justification *Justification `xml:"w:jc,omitempty"`
+ OutlineLevel *OutlineLevel `xml:"w:outlineLvl,omitempty"`
}
// ParagraphBorder 段落边框
@@ -95,15 +96,16 @@ type Shading struct {
}
// RunProperties 字符样式属性
+// 注意:字段顺序必须符合OpenXML标准,w:rFonts必须在w:color之前
type RunProperties struct {
XMLName xml.Name `xml:"w:rPr"`
+ FontFamily *FontFamily `xml:"w:rFonts,omitempty"`
Bold *Bold `xml:"w:b,omitempty"`
Italic *Italic `xml:"w:i,omitempty"`
Underline *Underline `xml:"w:u,omitempty"`
Strike *Strike `xml:"w:strike,omitempty"`
- FontSize *FontSize `xml:"w:sz,omitempty"`
Color *Color `xml:"w:color,omitempty"`
- FontFamily *FontFamily `xml:"w:rFonts,omitempty"`
+ FontSize *FontSize `xml:"w:sz,omitempty"`
Highlight *Highlight `xml:"w:highlight,omitempty"`
}