Golang实现JSON、XML与PNG数据整合生成PDF

Golang实现JSON、XML与PNG数据整合生成PDF xdg.me – 13 Nov 19

Go as glue: JSON + XML + PNG = PDF - xdg.me

将卡牌游戏的网络数据整合成可打印的卡牌替代品PDF。

一篇关于使用Go编写命令行程序的详细教程,该程序用于整合网络数据,为《指环王》卡牌游戏创建卡牌替代品的PDF。

1 回复

更多关于Golang实现JSON、XML与PNG数据整合生成PDF的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个典型的Go语言数据整合与PDF生成应用场景。以下是实现JSON、XML和PNG数据整合生成PDF的示例代码:

package main

import (
    "encoding/json"
    "encoding/xml"
    "fmt"
    "image"
    _ "image/png"
    "io"
    "net/http"
    "os"

    "github.com/jung-kurt/gofpdf"
)

// JSON数据结构
type CardData struct {
    ID     string `json:"id"`
    Name   string `json:"name"`
    Type   string `json:"type"`
    Cost   int    `json:"cost"`
    Attack int    `json:"attack"`
    Health int    `json:"health"`
    Image  string `json:"image_url"`
}

// XML数据结构
type CardXML struct {
    XMLName xml.Name `xml:"card"`
    ID      string   `xml:"id,attr"`
    Name    string   `xml:"name"`
    Text    string   `xml:"text"`
    Flavor  string   `xml:"flavor"`
}

// 从URL下载PNG图片
func downloadPNG(url string) (image.Image, error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    img, _, err := image.Decode(resp.Body)
    if err != nil {
        return nil, err
    }
    return img, nil
}

// 保存图片到临时文件
func saveImageToTemp(img image.Image, filename string) error {
    out, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer out.Close()

    // 这里需要根据实际图片格式使用相应的编码器
    // 示例中假设已经是PNG格式
    return nil
}

// 解析JSON数据
func parseJSONData(jsonStr string) ([]CardData, error) {
    var cards []CardData
    err := json.Unmarshal([]byte(jsonStr), &cards)
    if err != nil {
        return nil, err
    }
    return cards, nil
}

// 解析XML数据
func parseXMLData(xmlStr string) (CardXML, error) {
    var card CardXML
    err := xml.Unmarshal([]byte(xmlStr), &card)
    if err != nil {
        return CardXML{}, err
    }
    return card, nil
}

// 生成PDF
func generatePDF(cards []CardData, xmlData map[string]CardXML, outputPath string) error {
    pdf := gofpdf.New("P", "mm", "A4", "")
    
    for i, card := range cards {
        if i%4 == 0 {
            pdf.AddPage()
        }
        
        // 设置位置
        x := float64((i%4)%2)*100 + 10
        y := float64((i%4)/2)*150 + 10
        
        // 添加卡牌名称
        pdf.SetFont("Arial", "B", 12)
        pdf.SetXY(x, y)
        pdf.Cell(80, 10, card.Name)
        
        // 添加卡牌类型和费用
        pdf.SetFont("Arial", "", 10)
        pdf.SetXY(x, y+15)
        pdf.Cell(80, 10, fmt.Sprintf("%s - Cost: %d", card.Type, card.Cost))
        
        // 添加XML中的文本描述
        if xmlCard, ok := xmlData[card.ID]; ok {
            pdf.SetXY(x, y+30)
            pdf.MultiCell(80, 5, xmlCard.Text)
            
            pdf.SetFont("Arial", "I", 8)
            pdf.SetXY(x, y+60)
            pdf.Cell(80, 5, xmlCard.Flavor)
        }
        
        // 添加攻击和生命值
        if card.Attack > 0 || card.Health > 0 {
            pdf.SetFont("Arial", "B", 14)
            pdf.SetXY(x+60, y+70)
            pdf.Cell(20, 10, fmt.Sprintf("%d/%d", card.Attack, card.Health))
        }
        
        // 添加图片占位符
        pdf.SetFillColor(200, 200, 200)
        pdf.Rect(x, y+80, 80, 40, "F")
        pdf.SetXY(x, y+80)
        pdf.Cell(80, 40, "[Image: "+card.Name+"]")
    }
    
    return pdf.OutputFileAndClose(outputPath)
}

func main() {
    // 示例JSON数据
    jsonData := `[
        {"id": "001", "name": "Aragorn", "type": "Hero", "cost": 5, "attack": 3, "health": 5, "image_url": "https://example.com/aragorn.png"},
        {"id": "002", "name": "Gandalf", "type": "Hero", "cost": 6, "attack": 4, "health": 4, "image_url": "https://example.com/gandalf.png"}
    ]`
    
    // 示例XML数据
    xmlData := `<?xml version="1.0"?>
    <card id="001">
        <name>Aragorn</name>
        <text>Strider. Ranger of the North. Response: After Aragorn attacks, draw a card.</text>
        <flavor>All that is gold does not glitter</flavor>
    </card>`
    
    // 解析数据
    cards, err := parseJSONData(jsonData)
    if err != nil {
        fmt.Printf("Error parsing JSON: %v\n", err)
        return
    }
    
    xmlCard, err := parseXMLData(xmlData)
    if err != nil {
        fmt.Printf("Error parsing XML: %v\n", err)
        return
    }
    
    // 创建XML数据映射
    xmlMap := make(map[string]CardXML)
    xmlMap[xmlCard.ID] = xmlCard
    
    // 下载并处理图片
    for _, card := range cards {
        if card.Image != "" {
            img, err := downloadPNG(card.Image)
            if err != nil {
                fmt.Printf("Error downloading image for %s: %v\n", card.Name, err)
                continue
            }
            // 保存图片或直接处理
            _ = img // 实际使用中需要处理图片
        }
    }
    
    // 生成PDF
    err = generatePDF(cards, xmlMap, "cards.pdf")
    if err != nil {
        fmt.Printf("Error generating PDF: %v\n", err)
        return
    }
    
    fmt.Println("PDF generated successfully: cards.pdf")
}

需要安装的依赖:

go get github.com/jung-kurt/gofpdf

这个实现包含以下关键功能:

  1. JSON解析:解析卡牌的基本信息(名称、类型、费用等)
  2. XML解析:解析卡牌的详细描述和背景文本
  3. 图片处理:从网络下载PNG图片
  4. PDF生成:使用gofpdf库创建包含所有数据的PDF文件

每张卡牌在PDF中的布局包括:

  • 卡牌名称和类型
  • 费用、攻击力和生命值
  • XML中的描述文本和背景故事
  • 图片占位符区域

实际应用中需要根据具体的JSON和XML数据结构进行调整,并实现图片的实际嵌入功能(gofpdf支持添加JPEG和PNG图片)。

回到顶部