fumiama / go-docx

One of the most functional libraries to partially read and write .docx files (a.k.a. Microsoft Word documents or ECMA-376 Office Open XML) in Go.
GNU Affero General Public License v3.0
109 stars 14 forks source link

code issue #30

Open xiaohei417 opened 4 months ago

xiaohei417 commented 4 months ago

I want to add watermark or open file template re-write new file.

xiaohei417 commented 4 months ago

I want to read xxx.docx and write some text for xxx.docx, but no change after re-open file. please help check my code, thanks.

package main

import (
    "fmt"
    "os"

    "github.com/fumiama/go-docx"
)

func main() {
    readFile, err := os.Open("xxx.docx")
    if err != nil {
        panic(err)
    }
    fileinfo, err := readFile.Stat()
    if err != nil {
        panic(err)
    }
    size := fileinfo.Size()
    doc, err := docx.Parse(readFile, size)
    if err != nil {
        panic(err)
    }

    d := docx.LoadBodyItems(doc.Document.Body.Items, nil)
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    d.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    _, err = d.WriteTo(readFile)
    if err != nil {
        panic(err)
    }

    fmt.Println("Plain text:")
    for _, it := range d.Document.Body.Items {
        switch it.(type) {
        case *docx.Paragraph, *docx.Table: // printable
            fmt.Println(it)
        }
    }
}
xiaohei417 commented 4 months ago

我稍微调整了一下代码,出现了新的错误

package main

import (
    "fmt"
    "os"

    "github.com/fumiama/go-docx"
)

func main() {
    readFile, err := os.Open("xxx.docx")
    if err != nil {
        panic(err)
    }
    fileinfo, err := readFile.Stat()
    if err != nil {
        panic(err)
    }
    size := fileinfo.Size()
    doc, err := docx.Parse(readFile, size)
    if err != nil {
        panic(err)
    }

    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")
    doc.AddParagraph().AddText("ashfjklhsjakdhfkhas").Size("20")

    fmt.Println("Plain text:")
    for _, it := range doc.Document.Body.Items {
        switch it.(type) {
        case *docx.Paragraph, *docx.Table: // printable
            fmt.Println(it)
        }
    }

    f, err := os.Create("xxx2.docx")
    if err != nil {
        panic(err)
    }

    _, err = doc.WriteTo(f)
    if err != nil {
        panic(err)
    }
    f.Close()
}

image

fumiama commented 4 months ago

说明你的docx中包含一些本库尚未完全支持的内容。详见 #26

xiaohei417 commented 4 months ago

说明你的docx中包含一些本库尚未完全支持的内容。详见 #26

but my docx file only several lines text, my computer is mac intel

fumiama commented 4 months ago

说明你的docx中包含一些本库尚未完全支持的内容。详见 #26

but my docx file only several lines text, my computer is mac intel

可以发一下你的文件链接,我有空试试。

xiaohei417 commented 4 months ago

说明你的docx中包含一些本库尚未完全支持的内容。详见 #26

but my docx file only several lines text, my computer is mac intel

可以发一下你的文件链接,我有空试试。

xxx.docx

xiaohei417 commented 3 months ago

@fumiama 请问您那边尝试是否有问题?

willthrom commented 3 months ago

Hi @fumiama I think I have the same problem. I even went further, go to https://www.microsoft365.com/?auth=1 create a blank empty word docx document. I download it, then run a simple test, parse and write, the new file is not working in Microsoft Word or Google Word. I can open it with WordPad thought.

Here it is the code:

` func main() { readFile, err := os.Open("blank.docx") if err != nil { panic(err) } fileinfo, err := readFile.Stat() if err != nil { panic(err) } size := fileinfo.Size() doc, err := docx.Parse(readFile, size) if err != nil { panic(err) }

f, err := os.Create("xxx3.docx")
if err != nil {
    panic(err)
}

_, err = doc.WriteTo(f)
if err != nil {
    panic(err)
}
f.Close()

} `

Source file: blank.docx Generated file: xxx3.docx

willthrom commented 3 months ago

I did took a look to the doc document and the items after testing with unidoc what happened after reading/writting the file. Unidoc created lots of sections.

If I check for the last item in my generated document and remove the last one, if it is a sections, the word generate is valid and readable by Microsoft Office

// Sections seems to have a bug, so we need to remove the last 1 item if it is a section // interface {}(github.com/fumiama/go-docx.SectPr) {XMLName: encoding/xml.Name {Space: "", Local: ""}, PgSz: github.com/fumiama/go-docx.PgSz {W: ("encoding/xml.Attr")(0xc000234780), H: ("encoding/xml.Attr")(0xc0002347b0)}} if len(doc.Document.Body.Items) > 0 { if _, ok := doc.Document.Body.Items[len(doc.Document.Body.Items)-1].(docx.SectPr); ok { doc.Document.Body.Items = doc.Document.Body.Items[:len(doc.Document.Body.Items)-1] } }