Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

insert image into a specific place of docx file using golang

Tags:

go

docx

I am trying to fill a docx template dynamically using the golang package "github.com/lukasjarosch/go-docx".

enter image description here

I can replace all the text fields accordingly with this code:

package main

import (
    docx "github.com/lukasjarosch/go-docx"
)

func main() {
    // some logic here

    replaceMap := docx.PlaceholderMap{
        "personName":            name,
        "companyName":           company_name,
        "cityName":              city_name,
        // .....
    }

    // read and parse the template docx
    doc, err := docx.Open("rental_contract_template.docx")
    if err != nil {
        panic(err)
    }

    // replace the keys with values from replaceMap
    err = doc.ReplaceAll(replaceMap)
    if err != nil {
        panic(err)
    }

    // write out a new file
    err = doc.WriteToFile("replaced.docx")
    if err != nil {
        panic(err)
    }
}

Now I want to insert an image at {QRODE}. I found out that unfortunately, this package does not provide this functionality. I am lacking the knowledge to work with XML directly. I am supposed to not use "github.com/unidoc/unioffice".

How can I insert an image at that specific place?

like image 901
ABDULLOKH MUKHAMMADJONOV Avatar asked Oct 18 '25 08:10

ABDULLOKH MUKHAMMADJONOV


2 Answers

Do you want to try it ?

"github.com/nguyenthenguyen/docx"

this is example:

package main

import (
    "strconv"

    "github.com/nguyenthenguyen/docx"
)

func main() {
    // Read from docx file
    r, err := docx.ReadDocxFile("./TestDocument.docx")
    // Or read from memory
    // r, err := docx.ReadDocxFromMemory(data io.ReaderAt, size int64)

    // Or read from a filesystem object:
    // r, err := docx.ReadDocxFromFS(file string, fs fs.FS)

    if err != nil {
        panic(err)
    }
    docx1 := r.Editable()
    // Replace like https://golang.org/pkg/strings/#Replace
    docx1.Replace("old_1_1", "new_1_1", -1)
    docx1.Replace("old_1_2", "new_1_2", -1)
    docx1.ReplaceLink("http://example.com/", "https://github.com/nguyenthenguyen/docx", 1)
    docx1.ReplaceHeader("out with the old", "in with the new")
    docx1.ReplaceFooter("Change This Footer", "new footer")
    docx1.WriteToFile("./new_result_1.docx")

    docx2 := r.Editable()
    docx2.Replace("old_2_1", "new_2_1", -1)
    docx2.Replace("old_2_2", "new_2_2", -1)
    docx2.WriteToFile("./new_result_2.docx")

    // Or write to ioWriter
    // docx2.Write(ioWriter io.Writer)

    docx3 := r.Editable()
    //Currently only swaps apples for apples i.e. png to png, and not png to jpeg etc.
    docx3.ReplaceImage("word/media/image1.png", "./new.png")

    // replace the last image
    imageIndex := docx3.ImagesLen()
    docx3.ReplaceImage("word/media/image"+strconv.Itoa(imageIndex)+".png", "./new.png")
    docx3.WriteToFile("./new_result_3.docx")

    r.Close()
}

like image 153
yubin Avatar answered Oct 20 '25 04:10

yubin


I've made my own module that also supports image loading (png and jpg)

https://github.com/JJJJJJack/go-template-docx

first of all your template should be changed to match the go template syntax, like so: docx template

and this will be the code that will do the templating job done!

package main

import (
    "os"

    gotemplatedocx "github.com/JJJJJJack/go-template-docx"
)

func main() {
    // some logic here

    type tmpMap map[string]interface{}

    imageFilename := "qr_code.png"

    replaceMap := tmpMap{
        "PersonName":   "John Doe",
        "CompanyName":  "Company XYZ",
        "CityName":     "Night City",
        "CityCode":     1337,
        "Key1":         "Key1Value",
        "ServiceSpeed": "30 minutes",
        "LinkingWord":  "LinkingWordValue",
        "Place":        "Best Books Shop",
        "QrCodePng":    imageFilename,
    }

    docxTemplate, err := gotemplatedocx.NewDocxTemplateFromFilename("rental_contract_template.docx")
    if err != nil {
        panic(err)
    }

    pngBytes, err := os.ReadFile("path/to/your/image/" + imageFilename)
    if err != nil {
        panic(err)
    }

    docxTemplate.Media(imageFilename, pngBytes)

    err = docxTemplate.Apply(replaceMap)
    if err != nil {
        panic(err)
    }

    err = docxTemplate.Save("replaced.docx")
    if err != nil {
        panic(err)
    }
}

if you want to replace an image instead, I suggest to follow the documentation for the "replaceImage" template function

you can also use a []byte or a struct{} for the docxTemplate.Apply parameter, more info in the repo documentation...

...I also released an executable to load values from a separated json file, like this:

.\template_docx_windows_x64.exe "report-template.docx" .\try.json -i img1.png -i img2.png -i img3.jpg
like image 36
Jack Avatar answered Oct 20 '25 05:10

Jack



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!