更新文档和md操作示例

This commit is contained in:
zero
2025-06-04 18:34:01 +08:00
parent 971f3bcca5
commit 9d3057855f
6 changed files with 765 additions and 1135 deletions

View File

@@ -1,797 +0,0 @@
package main
import (
"bytes"
"fmt"
"image"
"image/color"
"image/png"
"log"
"os"
"path/filepath"
"github.com/ZeroHawkeye/wordZero/pkg/document"
)
// createSampleImage 创建一个示例图片
func createSampleImage(width, height int, bgColor color.RGBA, text string) []byte {
img := image.NewRGBA(image.Rect(0, 0, width, height))
// 填充背景色
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
img.Set(x, y, bgColor)
}
}
// 添加一个简单的边框
borderColor := color.RGBA{255 - bgColor.R, 255 - bgColor.G, 255 - bgColor.B, 255}
for x := 0; x < width; x++ {
img.Set(x, 0, borderColor)
img.Set(x, height-1, borderColor)
}
for y := 0; y < height; y++ {
img.Set(0, y, borderColor)
img.Set(width-1, y, borderColor)
}
var buf bytes.Buffer
png.Encode(&buf, img)
return buf.Bytes()
}
// saveImageToFile 将图片数据保存为文件
func saveImageToFile(imageData []byte, filePath string) error {
// 确保目录存在
dir := filepath.Dir(filePath)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("创建目录失败: %v", err)
}
// 写入文件
file, err := os.Create(filePath)
if err != nil {
return fmt.Errorf("创建文件失败: %v", err)
}
defer file.Close()
_, err = file.Write(imageData)
if err != nil {
return fmt.Errorf("写入文件失败: %v", err)
}
return nil
}
// addSectionTitle 添加带样式的章节标题
func addSectionTitle(doc *document.Document, title string, level int) {
doc.AddParagraph("")
para := doc.AddParagraph("")
if level == 1 {
para.AddFormattedText(title, &document.TextFormat{
Bold: true,
FontSize: 16,
FontColor: "0066CC",
})
} else {
para.AddFormattedText(title, &document.TextFormat{
Bold: true,
FontSize: 14,
FontColor: "333333",
})
}
doc.AddParagraph("")
}
// addDescription 添加功能描述
func addDescription(doc *document.Document, description string) {
para := doc.AddParagraph("")
para.AddFormattedText(description, &document.TextFormat{
FontSize: 11,
FontColor: "666666",
Italic: true,
})
doc.AddParagraph("")
}
func main() {
fmt.Println("=== WordZero 高级图片功能演示 ===")
// 创建新文档
doc := document.New()
// 添加文档标题
titlePara := doc.AddParagraph("")
titlePara.AddFormattedText("WordZero 图片功能完整演示", &document.TextFormat{
Bold: true,
FontSize: 20,
FontColor: "000080",
})
doc.AddParagraph("")
descPara := doc.AddParagraph("")
descPara.AddFormattedText("本文档演示了WordZero图片处理的各种功能包括图片位置、大小调整、文字环绕等特性。", &document.TextFormat{
FontSize: 12,
FontColor: "444444",
})
doc.AddParagraph("")
// 确保输出目录存在
outputDir := "examples/output"
imagesDir := outputDir + "/images"
if err := os.MkdirAll(imagesDir, 0755); err != nil {
log.Fatalf("创建输出目录失败: %v", err)
}
// ==================== 第一部分:基础图片插入 ====================
addSectionTitle(doc, "1. 基础图片插入功能", 1)
addDescription(doc, "演示基本的图片插入功能,包括从数据和文件两种方式添加图片。")
fmt.Println("1. 基础图片插入功能演示...")
// 创建一个蓝色的示例图片
basicImageData := createSampleImage(200, 120, color.RGBA{100, 150, 255, 255}, "基础图片")
basicImagePath := filepath.Join(imagesDir, "basic_image.png")
if err := saveImageToFile(basicImageData, basicImagePath); err != nil {
log.Fatalf("保存基础图片失败: %v", err)
}
basicImageInfo, err := doc.AddImageFromData(
basicImageData,
"basic_image.png",
document.ImageFormatPNG,
200,
120,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 50.0, // 50毫米宽度
Height: 30.0, // 30毫米高度
},
AltText: "基础演示图片",
Title: "这是一个基础的图片插入示例",
},
)
if err != nil {
log.Fatalf("添加基础图片失败: %v", err)
}
fmt.Printf(" 添加基础图片成功ID: %s\n", basicImageInfo.ID)
doc.AddParagraph("上面是一个基础的图片插入示例。图片默认以嵌入式inline方式显示会跟随文本流动。")
// ==================== 第二部分:图片位置控制 ====================
addSectionTitle(doc, "2. 图片位置控制功能", 1)
addDescription(doc, "演示不同的图片位置选项:嵌入式、左浮动、右浮动等。")
fmt.Println("2. 图片位置控制功能演示...")
// 2.1 嵌入式图片(默认)
addSectionTitle(doc, "2.1 嵌入式图片(默认位置)", 2)
doc.AddParagraph("嵌入式图片会跟随文本流,在文档中的固定位置显示,不会影响周围文本的布局。")
inlineImageData := createSampleImage(180, 100, color.RGBA{255, 100, 100, 255}, "嵌入式")
inlineImagePath := filepath.Join(imagesDir, "inline_image.png")
if err := saveImageToFile(inlineImageData, inlineImagePath); err != nil {
log.Fatalf("保存嵌入式图片失败: %v", err)
}
inlineImageInfo, err := doc.AddImageFromData(
inlineImageData,
"inline_image.png",
document.ImageFormatPNG,
180,
100,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 45.0,
Height: 25.0,
},
Position: document.ImagePositionInline,
WrapText: document.ImageWrapNone,
AltText: "嵌入式图片",
Title: "嵌入式图片示例",
},
)
if err != nil {
log.Fatalf("添加嵌入式图片失败: %v", err)
}
fmt.Printf(" 添加嵌入式图片成功ID: %s\n", inlineImageInfo.ID)
doc.AddParagraph("这段文字紧跟在嵌入式图片后面。嵌入式图片不会让文字环绕,而是按照正常的文档流进行排列。")
// 2.2 左浮动图片
addSectionTitle(doc, "2.2 左浮动图片", 2)
doc.AddParagraph("左浮动图片会显示在页面左侧,右侧的文字可以环绕显示。")
leftFloatImageData := createSampleImage(150, 150, color.RGBA{100, 255, 100, 255}, "左浮动")
leftFloatImagePath := filepath.Join(imagesDir, "left_float_image.png")
if err := saveImageToFile(leftFloatImageData, leftFloatImagePath); err != nil {
log.Fatalf("保存左浮动图片失败: %v", err)
}
leftFloatImageInfo, err := doc.AddImageFromData(
leftFloatImageData,
"left_float_image.png",
document.ImageFormatPNG,
150,
150,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 40.0,
Height: 40.0,
},
Position: document.ImagePositionFloatLeft,
WrapText: document.ImageWrapSquare,
AltText: "左浮动图片",
Title: "左浮动图片示例",
OffsetX: 2.0, // 距离左边2毫米
OffsetY: 0.0,
},
)
if err != nil {
log.Fatalf("添加左浮动图片失败: %v", err)
}
fmt.Printf(" 添加左浮动图片成功ID: %s\n", leftFloatImageInfo.ID)
doc.AddParagraph("这段文字演示了左浮动图片的效果。左浮动图片会靠左显示,而这段文字内容会在图片的右侧进行环绕显示。这种布局方式常用于杂志、报纸等出版物中,可以有效利用版面空间,让文档看起来更加美观和专业。左浮动图片适合在文章开头或段落中插入配图,不会打断阅读的连续性。")
// 2.3 右浮动图片
addSectionTitle(doc, "2.3 右浮动图片", 2)
doc.AddParagraph("右浮动图片会显示在页面右侧,左侧的文字可以环绕显示。")
rightFloatImageData := createSampleImage(160, 120, color.RGBA{255, 200, 100, 255}, "右浮动")
rightFloatImagePath := filepath.Join(imagesDir, "right_float_image.png")
if err := saveImageToFile(rightFloatImageData, rightFloatImagePath); err != nil {
log.Fatalf("保存右浮动图片失败: %v", err)
}
rightFloatImageInfo, err := doc.AddImageFromData(
rightFloatImageData,
"right_float_image.png",
document.ImageFormatPNG,
160,
120,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 42.0,
Height: 32.0,
},
Position: document.ImagePositionFloatRight,
WrapText: document.ImageWrapSquare,
AltText: "右浮动图片",
Title: "右浮动图片示例",
OffsetX: 2.0, // 距离右边2毫米
OffsetY: 0.0,
},
)
if err != nil {
log.Fatalf("添加右浮动图片失败: %v", err)
}
fmt.Printf(" 添加右浮动图片成功ID: %s\n", rightFloatImageInfo.ID)
doc.AddParagraph("这段文字展示了右浮动图片的效果。右浮动图片会出现在页面的右侧,文字内容会从左侧开始环绕显示。这种布局方式特别适合在文档中插入说明性图片、图表或装饰性元素。右浮动布局可以让读者在阅读主要内容的同时,方便地查看相关的图片信息,提升文档的可读性和视觉效果。")
// ==================== 第三部分:文字环绕方式 ====================
addSectionTitle(doc, "3. 文字环绕方式", 1)
addDescription(doc, "演示不同的文字环绕模式:无环绕、四周环绕、紧密环绕、上下环绕等。")
fmt.Println("3. 文字环绕方式演示...")
// 3.1 无环绕
addSectionTitle(doc, "3.1 无环绕模式", 2)
doc.AddParagraph("无环绕模式下,文字不会环绕图片,图片会独占一行或一个段落。")
noWrapImageData := createSampleImage(140, 100, color.RGBA{200, 100, 255, 255}, "无环绕")
noWrapImagePath := filepath.Join(imagesDir, "no_wrap_image.png")
if err := saveImageToFile(noWrapImageData, noWrapImagePath); err != nil {
log.Fatalf("保存无环绕图片失败: %v", err)
}
noWrapImageInfo, err := doc.AddImageFromData(
noWrapImageData,
"no_wrap_image.png",
document.ImageFormatPNG,
140,
100,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 35.0,
Height: 25.0,
},
Position: document.ImagePositionInline,
WrapText: document.ImageWrapNone,
AltText: "无环绕图片",
Title: "无环绕模式示例",
},
)
if err != nil {
log.Fatalf("添加无环绕图片失败: %v", err)
}
fmt.Printf(" 添加无环绕图片成功ID: %s\n", noWrapImageInfo.ID)
doc.AddParagraph("上面的图片使用了无环绕模式。在这种模式下,图片前后的文字会分别在图片的上方和下方显示,不会有文字出现在图片的左右两侧。")
// 3.2 四周环绕
addSectionTitle(doc, "3.2 四周环绕模式", 2)
doc.AddParagraph("四周环绕模式下,文字会在图片的四周进行环绕显示。")
squareWrapImageData := createSampleImage(130, 130, color.RGBA{100, 200, 255, 255}, "四周环绕")
squareWrapImagePath := filepath.Join(imagesDir, "square_wrap_image.png")
if err := saveImageToFile(squareWrapImageData, squareWrapImagePath); err != nil {
log.Fatalf("保存四周环绕图片失败: %v", err)
}
squareWrapImageInfo, err := doc.AddImageFromData(
squareWrapImageData,
"square_wrap_image.png",
document.ImageFormatPNG,
130,
130,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 35.0,
Height: 35.0,
},
Position: document.ImagePositionFloatLeft,
WrapText: document.ImageWrapSquare,
AltText: "四周环绕图片",
Title: "四周环绕模式示例",
OffsetX: 3.0,
OffsetY: 0.0,
},
)
if err != nil {
log.Fatalf("添加四周环绕图片失败: %v", err)
}
fmt.Printf(" 添加四周环绕图片成功ID: %s\n", squareWrapImageInfo.ID)
doc.AddParagraph("这段文字演示了四周环绕的效果。四周环绕是最常用的文字环绕方式,文字会按照图片的矩形边界进行环绕,在图片周围形成整齐的文字布局。这种方式适合大多数文档场景,特别是在需要在正文中插入图片时。四周环绕模式可以保持文档的整洁性,同时有效利用版面空间,让图片和文字和谐地组合在一起。")
// 3.3 紧密环绕
addSectionTitle(doc, "3.3 紧密环绕模式", 2)
doc.AddParagraph("紧密环绕模式下,文字会更贴近图片的实际轮廓进行环绕。")
tightWrapImageData := createSampleImage(120, 140, color.RGBA{255, 150, 100, 255}, "紧密环绕")
tightWrapImagePath := filepath.Join(imagesDir, "tight_wrap_image.png")
if err := saveImageToFile(tightWrapImageData, tightWrapImagePath); err != nil {
log.Fatalf("保存紧密环绕图片失败: %v", err)
}
tightWrapImageInfo, err := doc.AddImageFromData(
tightWrapImageData,
"tight_wrap_image.png",
document.ImageFormatPNG,
120,
140,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 32.0,
Height: 37.0,
},
Position: document.ImagePositionFloatRight,
WrapText: document.ImageWrapTight,
AltText: "紧密环绕图片",
Title: "紧密环绕模式示例",
OffsetX: 2.0,
OffsetY: 0.0,
},
)
if err != nil {
log.Fatalf("添加紧密环绕图片失败: %v", err)
}
fmt.Printf(" 添加紧密环绕图片成功ID: %s\n", tightWrapImageInfo.ID)
doc.AddParagraph("这段文字展示了紧密环绕模式的特点。与四周环绕不同,紧密环绕会让文字更贴近图片的实际边缘,可以获得更紧凑的布局效果。这种模式特别适合不规则形状的图片或者需要节省版面空间的场合。紧密环绕能够让文档看起来更加精致和专业,是高端出版物中常用的排版技巧。")
// 3.4 上下环绕
addSectionTitle(doc, "3.4 上下环绕模式", 2)
doc.AddParagraph("上下环绕模式下,文字只在图片的上方和下方显示,左右两侧留空。")
topBottomWrapImageData := createSampleImage(180, 80, color.RGBA{150, 255, 150, 255}, "上下环绕")
topBottomWrapImagePath := filepath.Join(imagesDir, "top_bottom_wrap_image.png")
if err := saveImageToFile(topBottomWrapImageData, topBottomWrapImagePath); err != nil {
log.Fatalf("保存上下环绕图片失败: %v", err)
}
topBottomWrapImageInfo, err := doc.AddImageFromData(
topBottomWrapImageData,
"top_bottom_wrap_image.png",
document.ImageFormatPNG,
180,
80,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 48.0,
Height: 21.0,
},
Position: document.ImagePositionInline,
WrapText: document.ImageWrapTopAndBottom,
AltText: "上下环绕图片",
Title: "上下环绕模式示例",
},
)
if err != nil {
log.Fatalf("添加上下环绕图片失败: %v", err)
}
fmt.Printf(" 添加上下环绕图片成功ID: %s\n", topBottomWrapImageInfo.ID)
doc.AddParagraph("上面的图片演示了上下环绕模式。在这种模式下,图片的左右两侧不会有文字,所有文字内容都会在图片的上方和下方显示。这种布局方式适合横向较宽的图片,如图表、流程图、横幅等,可以让图片获得更好的展示效果。")
// ==================== 第四部分:图片大小调整 ====================
addSectionTitle(doc, "4. 图片大小调整功能", 1)
addDescription(doc, "演示各种图片大小调整选项:固定尺寸、保持比例、动态调整等。")
fmt.Println("4. 图片大小调整功能演示...")
// 4.1 固定尺寸
addSectionTitle(doc, "4.1 固定尺寸设置", 2)
doc.AddParagraph("可以为图片设置固定的宽度和高度,完全控制图片的显示尺寸。")
fixedSizeImageData := createSampleImage(200, 150, color.RGBA{255, 180, 200, 255}, "固定尺寸")
fixedSizeImagePath := filepath.Join(imagesDir, "fixed_size_image.png")
if err := saveImageToFile(fixedSizeImageData, fixedSizeImagePath); err != nil {
log.Fatalf("保存固定尺寸图片失败: %v", err)
}
fixedSizeImageInfo, err := doc.AddImageFromData(
fixedSizeImageData,
"fixed_size_image.png",
document.ImageFormatPNG,
200,
150,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 60.0, // 固定宽度60毫米
Height: 40.0, // 固定高度40毫米
},
AltText: "固定尺寸图片",
Title: "固定尺寸设置示例",
},
)
if err != nil {
log.Fatalf("添加固定尺寸图片失败: %v", err)
}
fmt.Printf(" 添加固定尺寸图片成功ID: %s尺寸: 60x40毫米\n", fixedSizeImageInfo.ID)
doc.AddParagraph("上面的图片被设置为固定尺寸60x40毫米。固定尺寸设置不考虑原始图片的长宽比会严格按照指定的尺寸显示。")
// 4.2 保持长宽比
addSectionTitle(doc, "4.2 保持长宽比缩放", 2)
doc.AddParagraph("只设置宽度或高度,另一个维度自动计算以保持图片的原始长宽比。")
aspectRatioImageData := createSampleImage(300, 150, color.RGBA{180, 220, 255, 255}, "保持比例")
aspectRatioImagePath := filepath.Join(imagesDir, "aspect_ratio_image.png")
if err := saveImageToFile(aspectRatioImageData, aspectRatioImagePath); err != nil {
log.Fatalf("保存长宽比图片失败: %v", err)
}
aspectRatioImageInfo, err := doc.AddImageFromData(
aspectRatioImageData,
"aspect_ratio_image.png",
document.ImageFormatPNG,
300,
150,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 70.0, // 只设置宽度70毫米
KeepAspectRatio: true, // 保持长宽比
},
AltText: "保持长宽比图片",
Title: "保持长宽比缩放示例",
},
)
if err != nil {
log.Fatalf("添加长宽比图片失败: %v", err)
}
fmt.Printf(" 添加长宽比图片成功ID: %s宽度: 70毫米高度自动计算\n", aspectRatioImageInfo.ID)
doc.AddParagraph("上面的图片只设置了宽度为70毫米高度根据原始长宽比自动计算。这样可以避免图片变形保持图片的原始比例。")
// 4.3 动态调整大小
addSectionTitle(doc, "4.3 动态调整图片大小", 2)
doc.AddParagraph("演示在添加图片后动态调整其大小的功能。")
dynamicImageData := createSampleImage(160, 200, color.RGBA{200, 255, 180, 255}, "动态调整")
dynamicImagePath := filepath.Join(imagesDir, "dynamic_image.png")
if err := saveImageToFile(dynamicImageData, dynamicImagePath); err != nil {
log.Fatalf("保存动态调整图片失败: %v", err)
}
dynamicImageInfo, err := doc.AddImageFromData(
dynamicImageData,
"dynamic_image.png",
document.ImageFormatPNG,
160,
200,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 30.0, // 初始宽度30毫米
Height: 38.0, // 初始高度38毫米
},
AltText: "动态调整图片",
Title: "动态调整大小示例",
},
)
if err != nil {
log.Fatalf("添加动态调整图片失败: %v", err)
}
fmt.Printf(" 添加动态调整图片成功ID: %s初始尺寸: 30x38毫米\n", dynamicImageInfo.ID)
// 动态调整图片大小
newSize := &document.ImageSize{
Width: 50.0, // 调整为50毫米宽度
Height: 65.0, // 调整为65毫米高度
}
err = doc.ResizeImage(dynamicImageInfo, newSize)
if err != nil {
log.Fatalf("动态调整图片大小失败: %v", err)
}
fmt.Printf(" 图片大小已动态调整为50x65毫米\n")
doc.AddParagraph("上面的图片演示了动态大小调整。图片最初设置为30x38毫米然后通过ResizeImage方法调整为50x65毫米。")
// ==================== 第五部分:图片属性设置 ====================
addSectionTitle(doc, "5. 图片属性设置", 1)
addDescription(doc, "演示图片的各种属性设置:替代文字、标题、偏移量等。")
fmt.Println("5. 图片属性设置演示...")
// 创建用于属性设置演示的图片
propertiesImageData := createSampleImage(140, 110, color.RGBA{255, 220, 150, 255}, "属性设置")
propertiesImagePath := filepath.Join(imagesDir, "properties_image.png")
if err := saveImageToFile(propertiesImageData, propertiesImagePath); err != nil {
log.Fatalf("保存属性设置图片失败: %v", err)
}
propertiesImageInfo, err := doc.AddImageFromData(
propertiesImageData,
"properties_image.png",
document.ImageFormatPNG,
140,
110,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 35.0,
Height: 28.0,
},
Position: document.ImagePositionFloatRight,
WrapText: document.ImageWrapSquare,
OffsetX: 5.0, // 距离右边5毫米
OffsetY: 2.0, // 向下偏移2毫米
},
)
if err != nil {
log.Fatalf("添加属性设置图片失败: %v", err)
}
// 设置图片属性
err = doc.SetImageAltText(propertiesImageInfo, "这是一个用于演示属性设置的示例图片,包含了完整的可访问性信息")
if err != nil {
log.Fatalf("设置图片替代文字失败: %v", err)
}
err = doc.SetImageTitle(propertiesImageInfo, "图片属性设置演示 - 包含标题、替代文字和位置偏移")
if err != nil {
log.Fatalf("设置图片标题失败: %v", err)
}
fmt.Printf(" 添加属性设置图片成功ID: %s\n", propertiesImageInfo.ID)
fmt.Printf(" 设置了替代文字、标题和位置偏移\n")
doc.AddParagraph("这段文字旁边的图片演示了完整的属性设置功能。图片设置了详细的替代文字Alt Text这对于屏幕阅读器用户的可访问性非常重要。同时还设置了图片标题提供了额外的描述信息。图片位置设置了偏移量距离右边5毫米向下偏移2毫米可以实现精确的位置控制。这些属性设置让图片不仅在视觉上表现良好在可访问性方面也符合现代文档的标准要求。")
// ==================== 第六部分:综合应用示例 ====================
addSectionTitle(doc, "6. 综合应用示例", 1)
addDescription(doc, "展示在实际文档中综合运用各种图片功能的效果。")
fmt.Println("6. 综合应用示例演示...")
doc.AddParagraph("以下是一个模拟真实文档的综合示例,展示了如何在一篇文档中合理运用各种图片功能:")
// 综合示例:创建多个不同用途的图片
// 标题图片
headerImageData := createSampleImage(400, 120, color.RGBA{70, 130, 200, 255}, "文档标题")
headerImagePath := filepath.Join(imagesDir, "header_image.png")
if err := saveImageToFile(headerImageData, headerImagePath); err != nil {
log.Fatalf("保存标题图片失败: %v", err)
}
headerImageInfo, err := doc.AddImageFromData(
headerImageData,
"header_image.png",
document.ImageFormatPNG,
400,
120,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 100.0, // 100毫米宽度
KeepAspectRatio: true,
},
Position: document.ImagePositionInline,
WrapText: document.ImageWrapNone,
AltText: "文档头部横幅图片",
Title: "WordZero图片功能综合演示横幅",
},
)
if err != nil {
log.Fatalf("添加标题图片失败: %v", err)
}
fmt.Printf(" 添加文档横幅图片成功ID: %s\n", headerImageInfo.ID)
doc.AddParagraph("上方是文档的横幅图片,使用了嵌入式布局和保持长宽比的大小设置。")
// 左侧配图
leftSideImageData := createSampleImage(120, 160, color.RGBA{150, 200, 100, 255}, "左侧配图")
leftSideImagePath := filepath.Join(imagesDir, "left_side_image.png")
if err := saveImageToFile(leftSideImageData, leftSideImagePath); err != nil {
log.Fatalf("保存左侧配图失败: %v", err)
}
leftSideImageInfo, err := doc.AddImageFromData(
leftSideImageData,
"left_side_image.png",
document.ImageFormatPNG,
120,
160,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 30.0,
Height: 40.0,
},
Position: document.ImagePositionFloatLeft,
WrapText: document.ImageWrapTight,
AltText: "文章左侧配图",
Title: "左浮动紧密环绕配图示例",
OffsetX: 1.0,
OffsetY: 0.0,
},
)
if err != nil {
log.Fatalf("添加左侧配图失败: %v", err)
}
fmt.Printf(" 添加左侧配图成功ID: %s\n", leftSideImageInfo.ID)
doc.AddParagraph("这段文字展示了在实际文档中使用图片的效果。左侧的配图使用了左浮动和紧密环绕设置,文字会紧贴图片边缘环绕显示。这种布局在杂志、报告和营销材料中非常常见,可以有效提升文档的视觉吸引力和专业感。通过合理的图片布局,可以引导读者的视线,强调重要内容,同时让文档看起来更加生动有趣。")
// 右侧图表
chartImageData := createSampleImage(180, 140, color.RGBA{255, 160, 160, 255}, "数据图表")
chartImagePath := filepath.Join(imagesDir, "chart_image.png")
if err := saveImageToFile(chartImageData, chartImagePath); err != nil {
log.Fatalf("保存图表图片失败: %v", err)
}
chartImageInfo, err := doc.AddImageFromData(
chartImageData,
"chart_image.png",
document.ImageFormatPNG,
180,
140,
&document.ImageConfig{
Size: &document.ImageSize{
Width: 45.0,
Height: 35.0,
},
Position: document.ImagePositionFloatRight,
WrapText: document.ImageWrapSquare,
AltText: "数据分析图表",
Title: "展示统计数据的图表",
OffsetX: 3.0,
OffsetY: 1.0,
},
)
if err != nil {
log.Fatalf("添加图表图片失败: %v", err)
}
fmt.Printf(" 添加右侧图表成功ID: %s\n", chartImageInfo.ID)
doc.AddParagraph("右侧的图表展示了数据可视化的应用。在商业文档和技术报告中,图表是不可或缺的元素。通过右浮动和四周环绕的设置,图表可以与解释性文字完美结合,让数据更加清晰易懂。这种布局方式特别适合在分析报告、研究论文和业务提案中使用,可以有效传达复杂的信息内容。")
// ==================== 第七部分:功能总结 ====================
addSectionTitle(doc, "7. 功能特性总结", 1)
addDescription(doc, "总结WordZero图片功能的所有特性和应用场景。")
doc.AddParagraph("")
featureTitlePara := doc.AddParagraph("")
featureTitlePara.AddFormattedText("WordZero图片功能特性列表", &document.TextFormat{
Bold: true,
FontSize: 12,
})
doc.AddParagraph("")
// 创建功能列表
features := []string{
"支持PNG、JPEG、GIF三种主流图片格式",
"支持从文件和数据两种方式添加图片",
"提供嵌入式、左浮动、右浮动三种位置选项",
"支持无环绕、四周环绕、紧密环绕、上下环绕四种文字环绕模式",
"可设置固定尺寸或保持长宽比的大小调整",
"支持动态调整已添加图片的大小",
"提供位置偏移量设置,实现精确位置控制",
"包含完整的可访问性支持(替代文字、标题)",
"所有图片数据自动嵌入到Word文档中",
"兼容Microsoft Word和WPS Office",
}
for _, feature := range features {
featurePara := doc.AddParagraph("")
featurePara.AddFormattedText(fmt.Sprintf("• %s", feature), &document.TextFormat{
FontSize: 11,
})
}
doc.AddParagraph("")
scenarioTitlePara := doc.AddParagraph("")
scenarioTitlePara.AddFormattedText("应用场景:", &document.TextFormat{
Bold: true,
FontSize: 12,
})
doc.AddParagraph("")
scenarios := []string{
"技术文档:插入流程图、架构图、截图等",
"商业报告:添加图表、统计图、产品图片",
"学术论文:插入实验图片、数据可视化图表",
"营销材料:使用品牌图片、产品展示图",
"用户手册:添加操作截图、示意图",
"培训材料:插入教学图片、演示图表",
}
for _, scenario := range scenarios {
scenarioPara := doc.AddParagraph("")
scenarioPara.AddFormattedText(fmt.Sprintf("• %s", scenario), &document.TextFormat{
FontSize: 11,
})
}
// 添加结尾
doc.AddParagraph("")
endPara := doc.AddParagraph("")
endPara.AddFormattedText("本演示文档展示了WordZero图片功能的完整特性。通过灵活运用这些功能您可以创建出专业、美观的Word文档。", &document.TextFormat{
FontSize: 12,
FontColor: "666666",
Italic: true,
})
// 保存文档
outputFile := outputDir + "/advanced_image_demo.docx"
err = doc.Save(outputFile)
if err != nil {
log.Fatalf("保存文档失败: %v", err)
}
fmt.Printf("\n=== 高级图片功能演示完成 ===\n")
fmt.Printf("文档已保存到: %s\n", outputFile)
fmt.Printf("生成的图片文件保存在: %s\n", imagesDir)
fmt.Printf("生成的图片文件包括:\n")
imageFiles := []string{
"basic_image.png (基础图片蓝色200x120像素)",
"inline_image.png (嵌入式图片红色180x100像素)",
"left_float_image.png (左浮动图片绿色150x150像素)",
"right_float_image.png (右浮动图片橙色160x120像素)",
"no_wrap_image.png (无环绕图片紫色140x100像素)",
"square_wrap_image.png (四周环绕图片青色130x130像素)",
"tight_wrap_image.png (紧密环绕图片橙红色120x140像素)",
"top_bottom_wrap_image.png (上下环绕图片浅绿色180x80像素)",
"fixed_size_image.png (固定尺寸图片粉色200x150像素)",
"aspect_ratio_image.png (长宽比图片浅蓝色300x150像素)",
"dynamic_image.png (动态调整图片浅绿色160x200像素)",
"properties_image.png (属性设置图片浅黄色140x110像素)",
"header_image.png (横幅图片蓝色400x120像素)",
"left_side_image.png (左侧配图绿色120x160像素)",
"chart_image.png (图表图片浅红色180x140像素)",
}
for i, file := range imageFiles {
fmt.Printf(" %d. %s\n", i+1, file)
}
fmt.Printf("\n功能演示统计\n")
fmt.Printf("- 演示的图片数量: 15张\n")
fmt.Printf("- 覆盖的位置模式: 3种 (嵌入式、左浮动、右浮动)\n")
fmt.Printf("- 覆盖的环绕模式: 4种 (无环绕、四周环绕、紧密环绕、上下环绕)\n")
fmt.Printf("- 大小调整方式: 3种 (固定尺寸、保持比例、动态调整)\n")
fmt.Printf("- 应用场景演示: 6个部分\n")
fmt.Printf("- 文档章节: 7个主要部分\n")
fmt.Printf("\n您可以用Microsoft Word或WPS Office打开查看完整效果\n")
fmt.Println("\n=== 所有图片功能演示已完成 ===")
}

View File

@@ -1,300 +0,0 @@
package main
import (
"fmt"
"os"
"github.com/ZeroHawkeye/wordZero/pkg/markdown"
)
func main() {
fmt.Println("WordZero Markdown双向转换完整示例")
fmt.Println("===================================")
// 确保输出目录存在
outputDir := "examples/output"
err := os.MkdirAll(outputDir, 0755)
if err != nil {
fmt.Printf("❌ 创建输出目录失败: %v\n", err)
os.Exit(1)
}
// 演示1: Markdown转Word
demonstrateMarkdownToWord(outputDir)
// 演示2: Word转Markdown反向转换
demonstrateWordToMarkdown(outputDir)
// 演示3: 双向转换器使用
demonstrateBidirectionalConverter(outputDir)
// 演示4: 批量转换功能
demonstrateBatchConversion(outputDir)
fmt.Println("\n🎉 所有转换示例运行完成!")
}
// demonstrateMarkdownToWord 演示Markdown转Word功能
func demonstrateMarkdownToWord(outputDir string) {
fmt.Println("\n📝 演示1: Markdown → Word 转换")
fmt.Println("================================")
// 创建示例Markdown内容
markdownContent := `# WordZero Markdown双向转换功能
欢迎使用WordZero库的Markdown和Word文档双向转换功能
## 功能特性概览
WordZero现在支持**完整的双向转换**
### 🚀 Markdown → Word 转换
- **goldmark解析引擎**: 基于CommonMark 0.31.2规范
- **完整语法支持**: 标题、格式化、列表、表格、图片、链接
- **智能样式映射**: 自动应用Word标准样式
- **可配置选项**: GitHub风味Markdown、脚注、错误处理
### 🔄 Word → Markdown 反向转换
- **结构完整保持**: 保持原文档的层次结构
- **格式智能识别**: 自动识别并转换文本格式
- **图片导出支持**: 提取图片并生成引用
- **多种导出模式**: GFM表格、Setext标题等选项
### 文本格式化示例
- **粗体文本**展示
- *斜体文本*展示
- ` + "`行内代码`" + `展示
### 列表支持示例
#### 无序列表
- 功能A: 基础Markdown语法
- 功能B: GitHub风味扩展
- 功能C: 自定义配置选项
#### 有序列表
1. 安装WordZero库
2. 创建转换器实例
3. 调用转换方法
4. 处理转换结果
### 引用块示例
> 这是一个引用块示例,演示引用文本的转换效果。
>
> 引用块中可以包含多行内容在Word中会以特殊格式显示。
### 代码块示例
` + "```" + `go
// WordZero双向转换示例代码
package main
import "github.com/ZeroHawkeye/wordZero/pkg/markdown"
func main() {
// Markdown转Word
converter := markdown.NewConverter(markdown.DefaultOptions())
doc, _ := converter.ConvertString(markdownText, nil)
doc.Save("output.docx")
// Word转Markdown
exporter := markdown.NewExporter(markdown.DefaultExportOptions())
exporter.ExportToFile("input.docx", "output.md", nil)
}
` + "```" + `
---
## 技术实现亮点
### 🔧 核心技术栈
- **goldmark**: 高性能Markdown解析器
- **WordZero**: 原生Go Word文档处理
- **双向转换**: 无缝的格式转换支持
### 📋 支持的配置选项
- ✅ GitHub Flavored Markdown扩展
- ✅ 脚注和尾注支持
- ✅ 表格格式转换(待完善)
- ✅ 任务列表支持(待实现)
- ✅ 图片处理和路径解析
- ✅ 错误处理和进度报告
### 🎯 使用场景
1. **技术文档转换**: 从Markdown快速生成Word文档
2. **报告自动化**: 将Word报告转换为Markdown
3. **版本控制友好**: Word文档转为可diff的Markdown
4. **批量处理**: 大量文档的格式转换
## 总结
WordZero的双向转换功能为现代文档工作流提供了强大支持
无论是从轻量级的Markdown到专业的Word文档
还是反向的格式转换,都能满足不同场景的需求。`
// 创建转换器(使用高质量配置)
opts := markdown.HighQualityOptions()
opts.GenerateTOC = true
opts.TOCMaxLevel = 3
converter := markdown.NewConverter(opts)
fmt.Println("📝 正在转换Markdown内容...")
// 转换为Word文档
doc, err := converter.ConvertString(markdownContent, nil)
if err != nil {
fmt.Printf("❌ 转换失败: %v\n", err)
os.Exit(1)
}
// 保存Word文档
outputPath := outputDir + "/markdown_to_word_demo.docx"
err = doc.Save(outputPath)
if err != nil {
fmt.Printf("❌ 保存文档失败: %v\n", err)
os.Exit(1)
}
fmt.Printf("✅ Markdown转Word成功输出: %s\n", outputPath)
// 同时保存Markdown源文件供后续演示使用
markdownPath := outputDir + "/source_document.md"
err = os.WriteFile(markdownPath, []byte(markdownContent), 0644)
if err != nil {
fmt.Printf("❌ 保存Markdown文件失败: %v\n", err)
os.Exit(1)
}
}
// demonstrateWordToMarkdown 演示Word转Markdown功能
func demonstrateWordToMarkdown(outputDir string) {
fmt.Println("\n📄 演示2: Word → Markdown 反向转换")
fmt.Println("===================================")
// 使用上一步生成的Word文档
wordPath := outputDir + "/markdown_to_word_demo.docx"
markdownOutputPath := outputDir + "/word_to_markdown_result.md"
// 创建导出器(使用高质量配置)
exportOpts := markdown.HighQualityExportOptions()
exportOpts.ExtractImages = true
exportOpts.ImageOutputDir = outputDir + "/extracted_images"
exportOpts.UseGFMTables = true
exportOpts.IncludeMetadata = true
exporter := markdown.NewExporter(exportOpts)
fmt.Println("📄 正在将Word文档转换为Markdown...")
// 执行反向转换
err := exporter.ExportToFile(wordPath, markdownOutputPath, nil)
if err != nil {
fmt.Printf("❌ Word转Markdown失败: %v\n", err)
return
}
fmt.Printf("✅ Word转Markdown成功输出: %s\n", markdownOutputPath)
// 显示转换结果预览
content, err := os.ReadFile(markdownOutputPath)
if err == nil && len(content) > 0 {
preview := string(content)
if len(preview) > 300 {
preview = preview[:300] + "..."
}
fmt.Printf("📋 转换结果预览:\n%s\n", preview)
}
}
// demonstrateBidirectionalConverter 演示双向转换器
func demonstrateBidirectionalConverter(outputDir string) {
fmt.Println("\n🔄 演示3: 双向转换器统一接口")
fmt.Println("===============================")
// 创建双向转换器
converter := markdown.NewBidirectionalConverter(
markdown.HighQualityOptions(),
markdown.HighQualityExportOptions(),
)
// 测试自动类型检测转换
testCases := []struct {
input string
output string
desc string
}{
{
input: outputDir + "/source_document.md",
output: outputDir + "/auto_converted.docx",
desc: "Markdown自动转换为Word",
},
{
input: outputDir + "/markdown_to_word_demo.docx",
output: outputDir + "/auto_converted.md",
desc: "Word自动转换为Markdown",
},
}
for i, tc := range testCases {
fmt.Printf("🔄 测试%d: %s\n", i+1, tc.desc)
err := converter.AutoConvert(tc.input, tc.output)
if err != nil {
fmt.Printf("❌ 自动转换失败: %v\n", err)
continue
}
fmt.Printf("✅ 自动转换成功: %s\n", tc.output)
}
}
// demonstrateBatchConversion 演示批量转换功能
func demonstrateBatchConversion(outputDir string) {
fmt.Println("\n📦 演示4: 批量转换功能")
fmt.Println("=======================")
// 创建多个测试文件
testMarkdownFiles := []string{
outputDir + "/test1.md",
outputDir + "/test2.md",
outputDir + "/test3.md",
}
testContents := []string{
"# 测试文档1\n\n这是第一个测试文档。\n\n## 内容\n- 项目A\n- 项目B",
"# 测试文档2\n\n这是第二个测试文档。\n\n> 引用内容示例",
"# 测试文档3\n\n这是第三个测试文档。\n\n```go\nfmt.Println(\"Hello\")\n```",
}
// 创建测试文件
for i, content := range testContents {
err := os.WriteFile(testMarkdownFiles[i], []byte(content), 0644)
if err != nil {
fmt.Printf("❌ 创建测试文件失败: %v\n", err)
return
}
}
// 执行批量转换
converter := markdown.NewConverter(markdown.DefaultOptions())
batchOutputDir := outputDir + "/batch_output"
fmt.Println("📦 正在执行批量Markdown转Word...")
err := converter.BatchConvert(testMarkdownFiles, batchOutputDir, &markdown.ConvertOptions{
ProgressCallback: func(current, total int) {
fmt.Printf("📊 批量转换进度: %d/%d\n", current, total)
},
ErrorCallback: func(err error) {
fmt.Printf("⚠️ 转换警告: %v\n", err)
},
})
if err != nil {
fmt.Printf("❌ 批量转换失败: %v\n", err)
return
}
fmt.Printf("✅ 批量转换完成!输出目录: %s\n", batchOutputDir)
}

View File

@@ -8,67 +8,303 @@ import (
)
func main() {
// 示例Markdown内容,包含表格和任务列表
markdownContent := `# 表格和任务列表示例
// 全面的Markdown内容示例,涵盖所有支持的功能
markdownContent := `# WordZero Markdown 功能演示文档
## 表格示例
这是一个全面展示 WordZero Markdown 转换功能的演示文档。
下面是一个简单的表格:
## 1. 标题演示
| 姓名 | 年龄 | 城市 |
|--------|------|--------|
| 张三 | 25 | 北京 |
| 李四 | 30 | 上海 |
| 王五 | 28 | 广州 |
### 1.1 标题级别测试
## 任务列表示例
# 一级标题 (H1)
## 二级标题 (H2)
### 三级标题 (H3)
#### 四级标题 (H4)
##### 五级标题 (H5)
###### 六级标题 (H6)
待办事项:
## 2. 文本格式化
- [x] 完成项目需求分析
- [ ] 设计系统架构
- [ ] 实现核心功能
- [x] 用户管理
- [ ] 权限控制
- [ ] 数据存储
- [x] 编写测试用例
- [ ] 部署到生产环境
### 2.1 基础格式
## 混合内容
这里有**粗体文本**和*斜体文本*。
这是一个包含**粗体**和*斜体*的段落
你也可以组合使用***粗斜体文本***
### 对齐表格
还支持行内代码 ` + "`var x = \"hello world\"`" + `
| 左对齐 | 居中对齐 | 右对齐 |
|:-------|:--------:|-------:|
| 内容1 | 内容2 | 内容3 |
| 较长内容 | 短内容 | 数字 |
`
### 2.2 链接演示
// 创建转换器
这是一个[外部链接](https://github.com)的示例。
这是一个[WordZero项目链接](https://github.com/ZeroHawkeye/wordZero)。
## 3. 列表功能
### 3.1 无序列表
- 第一个项目
- 第二个项目
- 嵌套项目 1
- 嵌套项目 2
- 更深层嵌套
- 第三个项目
### 3.2 有序列表
1. 步骤一:准备工作
2. 步骤二:执行操作
1. 子步骤 2.1
2. 子步骤 2.2
3. 步骤三:验证结果
### 3.3 任务列表GitHub Flavored Markdown
**项目待办事项清单:**
- [x] ✅ 完成项目需求分析
- [x] ✅ 设计系统架构
- [ ] ⏳ 实现核心功能
- [x] ✅ 用户管理模块
- [x] ✅ 文档处理模块
- [ ] ⏳ 权限控制模块
- [ ] ⏳ 数据存储模块
- [x] ✅ 编写测试用例
- [ ] ⏳ 部署到生产环境
- [ ] ⏳ 编写用户文档
## 4. 表格功能
### 4.1 基础表格
| 功能特性 | 状态 | 优先级 | 备注 |
|----------|------|--------|------|
| 标题转换 | ✅ 完成 | 高 | 支持1-6级标题 |
| 文本格式 | ✅ 完成 | 高 | 粗体、斜体、代码 |
| 表格转换 | ✅ 完成 | 中 | 支持对齐方式 |
| 任务列表 | ✅ 完成 | 中 | GFM扩展功能 |
| 图片处理 | 🔄 开发中 | 低 | 基础支持 |
### 4.2 对齐方式表格
| 左对齐 | 居中对齐 | 右对齐 | 默认对齐 |
|:-------|:--------:|-------:|----------|
| 内容1 | 居中内容 | 右对齐内容 | 默认内容 |
| 较长的内容文本 | 短内容 | 数字123 | 普通文本 |
| Left | Center | Right | Normal |
### 4.3 复杂表格
| 序号 | 模块名称 | 实现状态 | 功能描述 | 测试覆盖率 |
|------|----------|----------|----------|------------|
| 1 | **核心解析器** | ✅ 已完成 | 基于goldmark的MD解析 | 95% |
| 2 | **文本渲染** | ✅ 已完成 | 支持格式化文本输出 | 90% |
| 3 | **表格处理** | ✅ 已完成 | *支持GFM表格规范* | 85% |
| 4 | **列表渲染** | ✅ 已完成 | 包含任务列表支持 | 88% |
| 5 | **图片处理** | 🔄 进行中 | 图片插入和路径处理 | 60% |
## 5. 代码块演示
### 5.1 内联代码
在Go语言中你可以使用 ` + "`fmt.Println(\"Hello, World!\")`" + ` 来输出文本。
创建变量:` + "`var name string = \"WordZero\"`" + `
### 5.2 代码块
` + "```" + `go
package main
import (
"fmt"
"github.com/ZeroHawkeye/wordZero/pkg/markdown"
)
func main() {
// 创建转换器
converter := markdown.NewConverter(markdown.HighQualityOptions())
// 转换文档
doc, err := converter.ConvertString(content, nil)
if err != nil {
log.Fatal(err)
}
// 保存文档
err = doc.Save("output.docx")
if err != nil {
log.Fatal(err)
}
fmt.Println("转换完成!")
}
` + "```" + `
` + "```" + `javascript
// JavaScript示例
function convertMarkdown(content) {
const options = {
enableGFM: true,
enableTables: true,
enableTaskList: true
};
return markdownConverter.convert(content, options);
}
` + "```" + `
` + "```" + `json
{
"project": "WordZero",
"version": "1.0.0",
"features": [
"markdown_conversion",
"table_support",
"task_lists",
"gfm_support"
],
"status": "active"
}
` + "```" + `
## 6. 引用块
### 6.1 简单引用
> 这是一个简单的引用块示例。
> 它可以包含多行内容。
### 6.2 嵌套引用
> 外层引用内容
>
> > 这是嵌套的引用内容
> > 可以包含更深层的内容
>
> 回到外层引用
### 6.3 引用中的格式
> **重要提示:** 在使用WordZero时请确保
>
> - 使用 *最新版本* 的库
> - 遵循 **官方文档** 的指导
> - 测试你的 ` + "`代码实现`" + `
## 7. 分割线
下面是一条分割线:
---
上面和下面都有分割线。
***
### 8.2 网络图片
![GitHub Logo](https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png)
## 9. 混合内容示例
这个段落包含**多种格式**,包括*斜体*、` + "`代码`" + `和[链接](https://example.com)。
### 9.1 复杂列表混合
1. **第一步:环境准备**
- 安装Go语言环境版本 >= 1.19
- 克隆项目:` + "`git clone https://github.com/ZeroHawkeye/wordZero.git`" + `
- 下载依赖:` + "`go mod download`" + `
2. **第二步:配置设置**
` + "```" + `bash
# 设置环境变量
export WORDZERO_CONFIG=./config.json
# 运行测试
go test ./...
` + "```" + `
3. **第三步:运行示例**
- [ ] 基础文档创建示例
- [x] Markdown转换示例
- [ ] 高级功能演示
- [x] 表格和列表演示
## 10. 功能特性总结
| 分类 | 功能点 | Markdown语法 | Word输出 | 状态 |
|------|--------|-------------|----------|------|
| **标题** | 1-6级标题 | ` + "`# ## ### #### ##### ######`" + ` | Heading样式 | ✅ |
| **格式** | 粗体 | ` + "`**text**`" + ` | Bold格式 | ✅ |
| **格式** | 斜体 | ` + "`*text*`" + ` | Italic格式 | ✅ |
| **格式** | 行内代码 | ` + "```text```" + ` | 等宽字体 | ✅ |
| **链接** | 超链接 | ` + "`[text](url)`" + ` | 蓝色文本 | ✅ |
| **列表** | 无序列表 | ` + "`- item`" + ` | 项目符号 | ✅ |
| **列表** | 有序列表 | ` + "`1. item`" + ` | 编号列表 | ✅ |
| **列表** | 任务列表 | ` + "`- [x] done`" + ` | 复选框 | ✅ |
| **表格** | GFM表格 | ` + "`| cell |`" + ` | Word表格 | ✅ |
| **代码** | 代码块 | ` + "```code```" + ` | 等宽字体块 | ✅ |
| **引用** | 引用块 | ` + "`> quote`" + ` | 斜体格式 | ✅ |
| **分割** | 分割线 | ` + "`---`" + ` | 横线 | ✅ |
| **图片** | 图片引用 | ` + "`![alt](src)`" + ` | 文本占位 | 🔄 |
---
**文档生成时间:** 2025年
**功能完整性:** 核心功能100%实现
> 📝 **说明:** 这个文档展示了WordZero Markdown转换器的所有主要功能。
> 所有标记为✅的功能都已完全实现并可正常使用。`
fmt.Println("🚀 开始创建全面的Markdown功能演示...")
// 创建高质量转换器配置
opts := markdown.HighQualityOptions()
opts.EnableTables = true
opts.EnableTaskList = true
opts.EnableGFM = true
opts.EnableFootnotes = true
opts.GenerateTOC = true
opts.TOCMaxLevel = 3
converter := markdown.NewConverter(opts)
// 转换为Word文档
doc, err := converter.ConvertString(markdownContent, opts)
if err != nil {
log.Fatalf("转换失败: %v", err)
log.Fatalf("转换失败: %v", err)
}
// 保存文档
outputPath := "examples/output/table_and_tasklist_demo.docx"
outputPath := "examples/output/comprehensive_markdown_demo.docx"
err = doc.Save(outputPath)
if err != nil {
log.Fatalf("保存文档失败: %v", err)
log.Fatalf("保存文档失败: %v", err)
}
fmt.Printf("✅ 表格和任务列表示例已保存到: %s\n", outputPath)
fmt.Println("📝 示例包含以下功能:")
fmt.Println(" • GFM表格转换为Word表格")
fmt.Println(" • 任务列表复选框显示")
fmt.Println(" • 表格对齐方式保持")
fmt.Println(" • 混合格式文本支持")
fmt.Printf("✅ 全面Markdown功能演示已保存到: %s\n", outputPath)
fmt.Println("\n📋 演示包含以下功能特性:")
fmt.Println(" 🔸 标题转换 (H1-H6)")
fmt.Println(" 🔸 文本格式化 (粗体、斜体、行内代码)")
fmt.Println(" 🔸 链接处理")
fmt.Println(" 🔸 列表支持 (有序、无序、嵌套)")
fmt.Println(" 🔸 任务列表 (GitHub Flavored Markdown)")
fmt.Println(" 🔸 表格转换 (支持对齐方式)")
fmt.Println(" 🔸 代码块 (多语言语法)")
fmt.Println(" 🔸 引用块 (支持嵌套)")
fmt.Println(" 🔸 分割线")
fmt.Println(" 🔸 图片引用 (基础支持)")
fmt.Println(" 🔸 混合内容处理")
fmt.Println("\n🎯 配置选项:")
fmt.Printf(" • GitHub Flavored Markdown: %v\n", opts.EnableGFM)
fmt.Printf(" • 表格支持: %v\n", opts.EnableTables)
fmt.Printf(" • 任务列表: %v\n", opts.EnableTaskList)
fmt.Printf(" • 脚注支持: %v\n", opts.EnableFootnotes)
fmt.Printf(" • 生成目录: %v\n", opts.GenerateTOC)
fmt.Printf(" • 目录最大级别: %d\n", opts.TOCMaxLevel)
fmt.Printf(" • 默认字体: %s\n", opts.DefaultFontFamily)
fmt.Printf(" • 默认字号: %.1f\n", opts.DefaultFontSize)
}

View File

@@ -0,0 +1,306 @@
package main
import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"github.com/ZeroHawkeye/wordZero/pkg/markdown"
)
func main() {
fmt.Println("🔄 WordZero - Word转Markdown功能演示")
fmt.Println("=====================================")
// 1. 准备输入和输出路径
inputPath := "examples/output/comprehensive_markdown_demo.docx"
outputDir := "examples/output"
outputPath := filepath.Join(outputDir, "converted_from_word.md")
imagesDir := filepath.Join(outputDir, "images")
// 检查输入文件是否存在
if _, err := os.Stat(inputPath); os.IsNotExist(err) {
fmt.Printf("⚠️ 输入文件不存在: %s\n", inputPath)
fmt.Println("💡 请先运行 table_and_tasklist_demo.go 生成示例Word文档")
return
}
// 确保输出目录存在
err := os.MkdirAll(outputDir, 0755)
if err != nil {
log.Fatalf("❌ 创建输出目录失败: %v", err)
}
// 2. 演示基础Word转Markdown功能
fmt.Println("\n📝 基础转换演示...")
demonstrateBasicConversion(inputPath, outputPath)
// 3. 演示高质量转换配置
fmt.Println("\n✨ 高质量转换演示...")
demonstrateHighQualityConversion(inputPath, imagesDir)
// 4. 演示自定义配置转换
fmt.Println("\n🔧 自定义配置演示...")
demonstrateCustomConversion(inputPath, outputDir)
// 5. 演示双向转换器
fmt.Println("\n🔄 双向转换演示...")
demonstrateBidirectionalConversion(inputPath, outputDir)
// 6. 演示批量转换
fmt.Println("\n📁 批量转换演示...")
demonstrateBatchConversion(outputDir)
fmt.Println("\n🎉 所有Word转Markdown演示完成")
fmt.Println("📂 查看输出文件: " + outputDir)
}
// demonstrateBasicConversion 演示基础转换功能
func demonstrateBasicConversion(inputPath, outputPath string) {
fmt.Printf(" 输入文件: %s\n", inputPath)
fmt.Printf(" 输出文件: %s\n", outputPath)
// 使用默认配置创建导出器
exporter := markdown.NewExporter(markdown.DefaultExportOptions())
// 执行转换
err := exporter.ExportToFile(inputPath, outputPath, nil)
if err != nil {
fmt.Printf(" ❌ 转换失败: %v\n", err)
return
}
fmt.Println(" ✅ 基础转换完成")
// 显示转换结果摘要
showFileInfo(outputPath)
}
// demonstrateHighQualityConversion 演示高质量转换
func demonstrateHighQualityConversion(inputPath, imagesDir string) {
outputPath := filepath.Join(filepath.Dir(imagesDir), "high_quality_conversion.md")
// 使用高质量配置
options := markdown.HighQualityExportOptions()
options.ImageOutputDir = imagesDir
options.ExtractImages = true
options.PreserveFootnotes = true
options.PreserveTOC = true
options.IncludeMetadata = true
// 添加进度回调
options.ProgressCallback = func(current, total int) {
fmt.Printf(" 📊 转换进度: %d/%d (%.1f%%)\n", current, total, float64(current)/float64(total)*100)
}
fmt.Printf(" 输入文件: %s\n", inputPath)
fmt.Printf(" 输出文件: %s\n", outputPath)
fmt.Printf(" 图片目录: %s\n", imagesDir)
exporter := markdown.NewExporter(options)
err := exporter.ExportToFile(inputPath, outputPath, nil)
if err != nil {
fmt.Printf(" ❌ 高质量转换失败: %v\n", err)
return
}
fmt.Println(" ✅ 高质量转换完成")
showFileInfo(outputPath)
}
// demonstrateCustomConversion 演示自定义配置转换
func demonstrateCustomConversion(inputPath, outputDir string) {
outputPath := filepath.Join(outputDir, "custom_conversion.md")
// 创建自定义配置
options := &markdown.ExportOptions{
// 表格和格式
UseGFMTables: true,
PreserveFootnotes: true,
PreserveLineBreaks: false,
WrapLongLines: true,
MaxLineLength: 80,
// 图片处理
ExtractImages: false, // 不导出图片文件
ImageRelativePath: true,
// 链接处理
PreserveBookmarks: true,
ConvertHyperlinks: true,
// 代码处理
PreserveCodeStyle: true,
DefaultCodeLang: "text",
// 内容处理
PreserveTOC: false,
IncludeMetadata: true,
StripComments: true,
// 格式化选项
UseSetext: false, // 使用ATX样式标题
BulletListMarker: "*", // 使用*作为项目符号
EmphasisMarker: "_", // 使用_表示斜体
// 错误处理
StrictMode: true,
IgnoreErrors: false,
ErrorCallback: func(err error) {
fmt.Printf(" ⚠️ 转换警告: %v\n", err)
},
}
fmt.Printf(" 输入文件: %s\n", inputPath)
fmt.Printf(" 输出文件: %s\n", outputPath)
fmt.Println(" 配置特点:")
fmt.Printf(" • GFM表格: %v\n", options.UseGFMTables)
fmt.Printf(" • 最大行长: %d字符\n", options.MaxLineLength)
fmt.Printf(" • 项目符号: %s\n", options.BulletListMarker)
fmt.Printf(" • 强调符号: %s\n", options.EmphasisMarker)
exporter := markdown.NewExporter(options)
err := exporter.ExportToFile(inputPath, outputPath, nil)
if err != nil {
fmt.Printf(" ❌ 自定义转换失败: %v\n", err)
return
}
fmt.Println(" ✅ 自定义转换完成")
showFileInfo(outputPath)
}
// demonstrateBidirectionalConversion 演示双向转换器
func demonstrateBidirectionalConversion(inputPath, outputDir string) {
// 创建双向转换器
converter := markdown.NewBidirectionalConverter(
markdown.HighQualityOptions(), // Markdown→Word选项
markdown.HighQualityExportOptions(), // Word→Markdown选项
)
// 测试Word→Markdown
mdPath := filepath.Join(outputDir, "bidirectional_word_to_md.md")
fmt.Printf(" Word→Markdown: %s → %s\n", inputPath, mdPath)
err := converter.AutoConvert(inputPath, mdPath)
if err != nil {
fmt.Printf(" ❌ Word→Markdown失败: %v\n", err)
return
}
fmt.Println(" ✅ Word→Markdown完成")
// 测试Markdown→Word (往回转换)
docxPath := filepath.Join(outputDir, "bidirectional_md_to_word.docx")
fmt.Printf(" Markdown→Word: %s → %s\n", mdPath, docxPath)
err = converter.AutoConvert(mdPath, docxPath)
if err != nil {
fmt.Printf(" ❌ Markdown→Word失败: %v\n", err)
return
}
fmt.Println(" ✅ Markdown→Word完成")
showFileInfo(mdPath)
showFileInfo(docxPath)
}
// demonstrateBatchConversion 演示批量转换
func demonstrateBatchConversion(outputDir string) {
// 准备批量转换的输入文件
inputFiles := []string{
"examples/output/comprehensive_markdown_demo.docx",
}
// 检查是否有其他可用的docx文件
files, err := filepath.Glob(filepath.Join(outputDir, "*.docx"))
if err == nil {
for _, file := range files {
if !contains(inputFiles, file) {
inputFiles = append(inputFiles, file)
}
}
}
if len(inputFiles) == 0 {
fmt.Println(" ⚠️ 没有找到可用于批量转换的Word文档")
return
}
batchOutputDir := filepath.Join(outputDir, "batch_converted")
fmt.Printf(" 输入文件数量: %d\n", len(inputFiles))
fmt.Printf(" 输出目录: %s\n", batchOutputDir)
// 配置批量转换选项
options := markdown.DefaultExportOptions()
options.ProgressCallback = func(current, total int) {
fmt.Printf(" 📊 批量转换进度: %d/%d\n", current, total)
}
options.ErrorCallback = func(err error) {
fmt.Printf(" ⚠️ 转换错误: %v\n", err)
}
// 执行批量转换
exporter := markdown.NewExporter(options)
err = exporter.BatchExport(inputFiles, batchOutputDir, options)
if err != nil {
fmt.Printf(" ❌ 批量转换失败: %v\n", err)
return
}
fmt.Println(" ✅ 批量转换完成")
// 显示转换结果
convertedFiles, _ := filepath.Glob(filepath.Join(batchOutputDir, "*.md"))
fmt.Printf(" 📄 成功转换 %d 个文件\n", len(convertedFiles))
for _, file := range convertedFiles {
fmt.Printf(" • %s\n", filepath.Base(file))
}
}
// showFileInfo 显示文件信息
func showFileInfo(filePath string) {
info, err := os.Stat(filePath)
if err != nil {
fmt.Printf(" 📄 文件信息获取失败: %v\n", err)
return
}
// 读取文件内容获取行数
content, err := os.ReadFile(filePath)
if err != nil {
fmt.Printf(" 📄 %s (大小: %d 字节)\n", filepath.Base(filePath), info.Size())
return
}
lines := len(strings.Split(string(content), "\n"))
fmt.Printf(" 📄 %s (大小: %d 字节, %d 行)\n", filepath.Base(filePath), info.Size(), lines)
// 显示前几行内容预览
preview := strings.Split(string(content), "\n")
maxPreview := 3
if len(preview) > maxPreview {
fmt.Println(" 📋 内容预览:")
for i := 0; i < maxPreview && i < len(preview); i++ {
line := preview[i]
if len(line) > 60 {
line = line[:57] + "..."
}
fmt.Printf(" %s\n", line)
}
if len(preview) > maxPreview {
fmt.Printf(" ... (还有 %d 行)\n", len(preview)-maxPreview)
}
}
}
// contains 检查切片是否包含指定元素
func contains(slice []string, item string) bool {
for _, s := range slice {
if s == item {
return true
}
}
return false
}

View File

@@ -967,6 +967,191 @@ options.StyleMapping = map[string]string{
converter := markdown.NewConverter(options)
```
## Word转Markdown功能 ✨ **新增功能**
WordZero现在支持将Word文档反向转换为Markdown格式提供完整的双向转换能力。
### Word导出器API
#### 导出器接口
- [`NewExporter(options *ExportOptions)`](../markdown/exporter.go) - 创建新的Word导出器
- [`DefaultExportOptions()`](../markdown/exporter.go) - 获取默认导出选项
- [`HighQualityExportOptions()`](../markdown/exporter.go) - 获取高质量导出选项
#### 导出方法
- [`ExportToFile(docxPath, mdPath string, options *ExportOptions)`](../markdown/exporter.go) - 导出Word文档到Markdown文件
- [`ExportToString(doc *Document, options *ExportOptions)`](../markdown/exporter.go) - 导出Word文档到Markdown字符串
- [`ExportToBytes(doc *Document, options *ExportOptions)`](../markdown/exporter.go) - 导出Word文档到Markdown字节数组
- [`BatchExport(inputs []string, outputDir string, options *ExportOptions)`](../markdown/exporter.go) - 批量导出Word文档
#### 导出配置选项 (`ExportOptions`)
- `UseGFMTables` - 使用GitHub风味Markdown表格
- `PreserveFootnotes` - 保留脚注
- `PreserveLineBreaks` - 保留换行符
- `WrapLongLines` - 自动换行
- `MaxLineLength` - 最大行长度
- `ExtractImages` - 导出图片文件
- `ImageOutputDir` - 图片输出目录
- `ImageNamePattern` - 图片命名模式
- `ImageRelativePath` - 使用相对路径
- `PreserveBookmarks` - 保留书签
- `ConvertHyperlinks` - 转换超链接
- `PreserveCodeStyle` - 保留代码样式
- `DefaultCodeLang` - 默认代码语言
- `IgnoreUnknownStyles` - 忽略未知样式
- `PreserveTOC` - 保留目录
- `IncludeMetadata` - 包含文档元数据
- `StripComments` - 删除注释
- `UseSetext` - 使用Setext样式标题
- `BulletListMarker` - 项目符号标记
- `EmphasisMarker` - 强调标记
- `StrictMode` - 严格模式
- `IgnoreErrors` - 忽略错误
- `ErrorCallback` - 错误回调函数
- `ProgressCallback` - 进度回调函数
### Word→Markdown转换映射
| Word元素 | Markdown语法 | 说明 |
|----------|-------------|------|
| Heading1-6 | `# ## ### #### ##### ######` | 标题级别对应 |
| 粗体 | `**粗体**` | 文本格式 |
| 斜体 | `*斜体*` | 文本格式 |
| 删除线 | `~~删除线~~` | 文本格式 |
| 行内代码 | `` `代码` `` | 代码格式 |
| 代码块 | ```` 代码块 ```` | 代码块 |
| 超链接 | `[链接文本](URL)` | 链接转换 |
| 图片 | `![图片](路径)` | 图片引用 |
| 表格 | `\| 表格 \|` | GFM表格格式 |
| 无序列表 | `- 项目` | 列表项 |
| 有序列表 | `1. 项目` | 编号列表 |
| 引用块 | `> 引用内容` | 引用格式 |
### Word转Markdown使用示例
#### 基础文件导出
```go
import "github.com/ZeroHawkeye/wordZero/pkg/markdown"
// 创建导出器
exporter := markdown.NewExporter(markdown.DefaultExportOptions())
// 导出Word文档为Markdown
err := exporter.ExportToFile("document.docx", "output.md", nil)
if err != nil {
log.Fatal(err)
}
```
#### 导出为字符串
```go
// 打开Word文档
doc, err := document.Open("document.docx")
if err != nil {
log.Fatal(err)
}
// 导出为Markdown字符串
exporter := markdown.NewExporter(markdown.DefaultExportOptions())
markdownText, err := exporter.ExportToString(doc, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(markdownText)
```
#### 高质量导出配置
```go
// 高质量导出配置
options := &markdown.ExportOptions{
UseGFMTables: true, // 使用GFM表格
ExtractImages: true, // 导出图片
ImageOutputDir: "./images", // 图片目录
PreserveFootnotes: true, // 保留脚注
IncludeMetadata: true, // 包含元数据
ConvertHyperlinks: true, // 转换超链接
PreserveCodeStyle: true, // 保留代码样式
UseSetext: false, // 使用ATX标题
BulletListMarker: "-", // 使用短横线
EmphasisMarker: "*", // 使用星号
ProgressCallback: func(current, total int) {
fmt.Printf("导出进度: %d/%d\n", current, total)
},
}
exporter := markdown.NewExporter(options)
err := exporter.ExportToFile("complex_document.docx", "output.md", options)
```
#### 批量导出示例
```go
// 批量导出Word文档
files := []string{"doc1.docx", "doc2.docx", "doc3.docx"}
options := &markdown.ExportOptions{
ExtractImages: true,
ImageOutputDir: "extracted_images/",
UseGFMTables: true,
ProgressCallback: func(current, total int) {
fmt.Printf("批量导出进度: %d/%d\n", current, total)
},
}
exporter := markdown.NewExporter(options)
err := exporter.BatchExport(files, "markdown_output/", options)
```
## 双向转换器 ✨ **统一接口**
### 双向转换器API
- [`NewBidirectionalConverter(mdOpts *ConvertOptions, exportOpts *ExportOptions)`](../markdown/exporter.go) - 创建双向转换器
- [`AutoConvert(inputPath, outputPath string)`](../markdown/exporter.go) - 自动检测文件类型并转换
### 双向转换使用示例
#### 自动转换
```go
import "github.com/ZeroHawkeye/wordZero/pkg/markdown"
// 创建双向转换器
converter := markdown.NewBidirectionalConverter(
markdown.HighQualityOptions(), // Markdown→Word选项
markdown.HighQualityExportOptions(), // Word→Markdown选项
)
// 自动检测文件类型并转换
err := converter.AutoConvert("input.docx", "output.md") // Word→Markdown
err = converter.AutoConvert("input.md", "output.docx") // Markdown→Word
```
#### 配置独立的转换方向
```go
// Markdown转Word配置
mdToWordOpts := &markdown.ConvertOptions{
EnableGFM: true,
EnableTables: true,
GenerateTOC: true,
DefaultFontFamily: "Calibri",
DefaultFontSize: 11.0,
}
// Word转Markdown配置
wordToMdOpts := &markdown.ExportOptions{
UseGFMTables: true,
ExtractImages: true,
ImageOutputDir: "./images",
PreserveFootnotes: true,
ConvertHyperlinks: true,
}
// 创建双向转换器
converter := markdown.NewBidirectionalConverter(mdToWordOpts, wordToMdOpts)
// 执行转换
err := converter.AutoConvert("document.docx", "document.md")
```
### 技术特性
#### 架构设计

Submodule wordZero.wiki updated: 31decacb58...defe2f93fc