f
This commit is contained in:
60
cmd/qygl_report_pdf/main.go
Normal file
60
cmd/qygl_report_pdf/main.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"tyapi-server/internal/shared/pdf"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 一个本地调试用的小工具:
|
||||||
|
// 从 JSON 文件(企业报告.json)读取 QYGL 聚合结果,使用 gofpdf 生成企业全景报告 PDF,输出到当前目录。
|
||||||
|
func main() {
|
||||||
|
var (
|
||||||
|
jsonPath string
|
||||||
|
outPath string
|
||||||
|
)
|
||||||
|
flag.StringVar(&jsonPath, "json", "企业报告.json", "企业报告 JSON 数据源文件路径")
|
||||||
|
flag.StringVar(&outPath, "out", "企业全景报告_gofpdf.pdf", "输出 PDF 文件路径")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
logger, _ := zap.NewDevelopment()
|
||||||
|
defer logger.Sync()
|
||||||
|
|
||||||
|
absJSON, _ := filepath.Abs(jsonPath)
|
||||||
|
fmt.Printf("读取 JSON 数据源:%s\n", absJSON)
|
||||||
|
|
||||||
|
data, err := os.ReadFile(jsonPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("读取 JSON 文件失败: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var report map[string]interface{}
|
||||||
|
if err := json.Unmarshal(data, &report); err != nil {
|
||||||
|
fmt.Printf("解析 JSON 失败: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("开始使用 gofpdf 生成企业全景报告 PDF...")
|
||||||
|
pdfBytes, err := pdf.GenerateQYGLReportPDF(context.Background(), logger, report)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("生成 PDF 失败: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile(outPath, pdfBytes, 0644); err != nil {
|
||||||
|
fmt.Printf("写入 PDF 文件失败: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
absOut, _ := filepath.Abs(outPath)
|
||||||
|
fmt.Printf("PDF 生成完成:%s\n", absOut)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@ package pdf
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"github.com/jung-kurt/gofpdf/v2"
|
"github.com/jung-kurt/gofpdf/v2"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@@ -131,22 +132,20 @@ func (fm *FontManager) tryAddFont(pdf *gofpdf.Fpdf, fontPath, fontName string) b
|
|||||||
// 注意:ToSlash不会改变路径的绝对/相对性质,只统一分隔符
|
// 注意:ToSlash不会改变路径的绝对/相对性质,只统一分隔符
|
||||||
normalizedPath := filepath.ToSlash(absFontPath)
|
normalizedPath := filepath.ToSlash(absFontPath)
|
||||||
|
|
||||||
// 在Linux下,绝对路径必须以/开头
|
// 在 Linux 下,绝对路径通常以 / 开头;在 Windows 下则可能以盘符 (C:/...) 开头。
|
||||||
// 如果normalizedPath不是以/开头,说明转换有问题
|
// 这里只要保证 normalizedPath 非空即可,具体格式交给 gofpdf 处理,避免在 Windows 下误判。
|
||||||
if len(normalizedPath) == 0 || normalizedPath[0] != '/' {
|
if len(normalizedPath) == 0 {
|
||||||
fm.logger.Error("字体路径转换后不是绝对路径(不以/开头)",
|
fm.logger.Error("字体路径转换后为空,无法添加到PDF",
|
||||||
zap.String("abs_font_path", absFontPath),
|
zap.String("abs_font_path", absFontPath),
|
||||||
|
zap.String("font_name", fontName),
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// 额外记录当前平台,方便排查路径格式问题
|
||||||
|
fm.logger.Debug("字体路径平台信息",
|
||||||
|
zap.String("goos", runtime.GOOS),
|
||||||
zap.String("normalized_path", normalizedPath),
|
zap.String("normalized_path", normalizedPath),
|
||||||
)
|
)
|
||||||
// 重新转换为绝对路径
|
|
||||||
if newAbsPath, err := filepath.Abs(absFontPath); err == nil {
|
|
||||||
absFontPath = newAbsPath
|
|
||||||
normalizedPath = filepath.ToSlash(newAbsPath)
|
|
||||||
fm.logger.Info("重新转换后的路径",
|
|
||||||
zap.String("new_normalized_path", normalizedPath),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fm.logger.Debug("准备添加字体到gofpdf",
|
fm.logger.Debug("准备添加字体到gofpdf",
|
||||||
zap.String("original_path", fontPath),
|
zap.String("original_path", fontPath),
|
||||||
@@ -157,16 +156,6 @@ func (fm *FontManager) tryAddFont(pdf *gofpdf.Fpdf, fontPath, fontName string) b
|
|||||||
|
|
||||||
// gofpdf v2使用AddUTF8Font添加支持UTF-8的字体
|
// gofpdf v2使用AddUTF8Font添加支持UTF-8的字体
|
||||||
// 注意:gofpdf在Output时可能会重新解析路径,必须确保路径格式正确
|
// 注意:gofpdf在Output时可能会重新解析路径,必须确保路径格式正确
|
||||||
// 关键:确保路径是绝对路径且以/开头,并使用filepath.ToSlash统一分隔符
|
|
||||||
// 如果normalizedPath不是以/开头,说明路径有问题,需要重新处理
|
|
||||||
if len(normalizedPath) == 0 || normalizedPath[0] != '/' {
|
|
||||||
fm.logger.Error("字体路径格式错误,无法添加到PDF",
|
|
||||||
zap.String("normalized_path", normalizedPath),
|
|
||||||
zap.String("font_name", fontName),
|
|
||||||
)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 记录传递给gofpdf的实际路径
|
// 记录传递给gofpdf的实际路径
|
||||||
fm.logger.Info("添加字体到gofpdf",
|
fm.logger.Info("添加字体到gofpdf",
|
||||||
zap.String("font_path", normalizedPath),
|
zap.String("font_path", normalizedPath),
|
||||||
|
|||||||
1811
internal/shared/pdf/qygl_report_pdf.go
Normal file
1811
internal/shared/pdf/qygl_report_pdf.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -474,15 +474,17 @@
|
|||||||
.section-card {
|
.section-card {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
page-break-inside: avoid;
|
/* 允许在模块内部分页,减少页面底部的空白 */
|
||||||
break-inside: avoid;
|
page-break-inside: auto;
|
||||||
|
break-inside: auto;
|
||||||
}
|
}
|
||||||
.section-card h2 {
|
.section-card h2 {
|
||||||
page-break-after: avoid;
|
page-break-after: avoid;
|
||||||
}
|
}
|
||||||
.item-list li {
|
.item-list li {
|
||||||
page-break-inside: avoid;
|
/* 列表项允许在需要时被分页拆分 */
|
||||||
break-inside: avoid;
|
page-break-inside: auto;
|
||||||
|
break-inside: auto;
|
||||||
}
|
}
|
||||||
/* 原始 JSON 展示在 PDF 中通常不需要过高容器限制 */
|
/* 原始 JSON 展示在 PDF 中通常不需要过高容器限制 */
|
||||||
.raw-section pre {
|
.raw-section pre {
|
||||||
@@ -661,6 +663,12 @@
|
|||||||
isListed: "是否上市",
|
isListed: "是否上市",
|
||||||
company: "上市公司信息",
|
company: "上市公司信息",
|
||||||
stock: "股票信息",
|
stock: "股票信息",
|
||||||
|
// 上市公司信息字段
|
||||||
|
bizScope: "经营范围",
|
||||||
|
regAddr: "注册地址",
|
||||||
|
regCapital: "注册资本",
|
||||||
|
cur: "币种",
|
||||||
|
curName: "币种名称",
|
||||||
};
|
};
|
||||||
|
|
||||||
function label(key) {
|
function label(key) {
|
||||||
|
|||||||
Reference in New Issue
Block a user