Closed huangchengwu closed 6 months ago
2023/11/30 14:00:18 open _rels/: invalid argument 报错
package main
import ( "log" "os"
"github.com/fumiama/go-docx"
)
func main() { readFile, err := os.OpenFile("测试表格.docx", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0755)
if err != nil {
log.Println(err)
}
fileinfo, err := readFile.Stat()
if err != nil {
log.Println(err)
}
size := fileinfo.Size()
doc, err := docx.Parse(readFile, size)
if err != nil {
log.Println(err)
}
defer readFile.Close()
for _, it := range doc.Document.Body.Items {
switch o := it.(type) {
case *docx.Paragraph: // printable
o.Properties = nil
case *docx.Table: // printable
o.TableRows[0].TableCells[1].Paragraphs[0].AddText("ss").Shade("clear", "auto", "E7E6E6")
}
}
// save to file
if err != nil {
panic(err)
}
_, err = doc.WriteTo(readFile)
if err != nil {
log.Println(err)
}
err = readFile.Close()
if err != nil {
log.Println(err)
}
}
不要用 os.OpenFile, os.O_RDWR|os.O_APPEND|os.O_CREATE 参数会打开文件并定位置最末尾
, 所以无法解析出任何内容。你直接运行我的示例程序,在它的基础上修改即可。
我的需求很简单就是打开旧的docx 进行修改后保存 ,但是我发现你的示例没有这个操作都是新建写入然后保存
docx本质是zip,无法实现直接修改,都是要全部重写。你要真的要覆盖,就Close后用os.Create重新打开文件WriteTo。
package main
import ( "fmt" "log" "os"
"github.com/fumiama/go-docx"
)
func DocAdd() { w := docx.NewA4() // add new paragraph para1 := w.AddParagraph() // add text para1.AddText("test").AddTab() para1.AddText("size").Size("44").AddTab() tbl2 := w.AddTableTwips([]int64{2333, 2333, 2333}, []int64{2333, 2333}).Justification("center") tbl2.TableRows[0].TableCells[0].Shade("clear", "auto", "E7E6E6")
f, err := os.Create("generated.docx")
// save to file
if err != nil {
panic(err)
}
_, err = w.WriteTo(f)
if err != nil {
panic(err)
}
err = f.Close()
if err != nil {
panic(err)
}
log.Println(w.Document.Body.Items)
} func main() { readFile, err := os.OpenFile("测试表格.docx", os.O_RDWR, 0644)
if err != nil {
log.Println(err)
}
fileinfo, err := readFile.Stat()
if err != nil {
log.Println(err)
}
size := fileinfo.Size()
doc, err := docx.Parse(readFile, size)
if err != nil {
log.Println(err)
}
defer readFile.Close()
for _, it := range doc.Document.Body.Items {
switch o := it.(type) {
case *docx.Paragraph: // printable
o.Properties = nil
case *docx.Table: // printable
fmt.Println(o)
o.TableRows[0].TableCells[1].Paragraphs[0].AddText("ss").Shade("clear", "auto", "E7E6E6")
// for _, tr := range o.TableRows {
// for _, tc := range tr.TableCells {
// for _, p := range tc.Paragraphs {
// if p.String() == "活动名称" {
// fmt.Println("==add", o.TableRows[1].TableCells[1])
// p.AddText("add")
// }
// p.Properties = nil
// }
// }
// }
}
fmt.Println(it)
}
// f, err := os.Create("generated.docx")
// newFile := docx.NewA4()
// para1 := newFile.AddParagraph()
// // add text
// para1.AddText("test").AddTab()
// para1.AddText("size").Size("44").AddTab()
// tbl2 := doc.AddTableTwips([]int64{2333, 2333, 2333}, []int64{2333, 2333}).Justification("end")
// tbl2.TableRows[0].TableCells[0].Shade("clear", "auto", "E7E6E6")
// tbl2.TableRows[0].TableCells[0].AddParagraph().AddText("test11").AddTab()
// tbl2.TableRows[0].TableCells[1].AddParagraph().AddText("test22").AddTab()
// tbl2.TableRows[1].TableCells[1].AddParagraph().AddText("test22").AddTab()
// tbl2.TableRows[2].TableCells[0].AddParagraph().Justification("center").AddText("test22").AddTab().Font("宋体", "宋体", "eastAsia").Bold()
// newFile.AppendFile(doc)
// _, err = io.Copy(f, newFile)
// if err != nil {
// log.Println(err)
// }
}
不是很理解 是close后在打开在拷贝吗 ,这个是我新的例子拷贝数据过去建新的但是还是存在跟原先不一样的情况
你是指就算直接读取后保存,也会和原文档不一样是吧,这是因为这个库并没有支持全部docx元素。
![Uploading 1701325392770.jpg…]() ![Uploading 1701325392770.jpg…]()
![Uploading 1701325392770.jpg…]()
![Uploading 1701325392770.jpg…]()
上传不了图片 就是两个表格一个短了一个还是原来的样子
就是页边距没复制过来
可以调整页边距吗
不行。你可以尝试添加此功能或使用默认页边距。
那我还要最后一个需求,
for _, it := range doc.Document.Body.Items {
switch o := it.(type) {
case *docx.Paragraph: // printable
o.Justification("center")
fmt.Println("==Paragraph", o)
// o.Properties = nil
case *docx.Table: // printable
o.TableRows[0].TableCells[1].Paragraphs[0].AddText("ss").Shade("clear", "auto", "E7E6E6")
// for _, tr := range o.TableRows {
// for _, tc := range tr.TableCells {
// for _, p := range tc.Paragraphs {
// if p.String() == "活动名称" {
// fmt.Println("==add", o.TableRows[1].TableCells[1])
// p.AddText("add")
// }
// p.Properties = nil
// }
// }
// }
}
fmt.Println(it)
}
这里面 *docx.Paragraph 我可以替换掉这个字段吗
可以啊,doc.Document.Body.Items 你想换啥换啥
创建一个对象然后替换到对应索引的Items 就可以了吗
可以,你也可以直接改拿到的paragraph,办法很多。
如何读写修改docx文件并且保存呢 WriteTo 方法并不能保存修改