go语言自动化编写word

文章目录

    • 背景
    • 步骤
      • 确定流程
      • 编写伪代码
      • 编写正式的代码
    • 最终的代码
    • 问题


关键字: word go语言 办公软件 自动化 excel office

背景

近来因为工作需要,经常性要重复地写报告,搞安全的就是苦逼啊。每次都需要人工查这查那,还要复制黏贴。 重复地复制黏贴会比较烦人。所以弄好一份表就自动让机器代替人工黏贴到word文档,自动生成会相对舒服且快速,有什么问题直接修改excel即可。

步骤

我是用go语言进行开发的。
go的版本:14
office使用的是:unioffice库
== 地址:https://github.com/unidoc/unioffice ==

第二个需要用到的库是:docx
==地址:https://github.com/nguyenthenguyen/docx ==

ps:
第一个库没研究透是什么情况,主要用来替换多行内容的。比如我有三个内容需要写进docx,但是只做了一行的标记,替换的时候只会替换第一个内容。那么第二、第三个内容就无法写进去了。这个时候只能用unidoc这个库来写入更多的内容且自动换行。
那么为什么需要第二个库呢,因为第二个库,简单直接,只能根据标记替换。且在页眉替换的时候不影响水印。 简单直接。缺点就是无法找到标记的内容,进行多行写入。

确定流程

其实最好先确定一下程序的处理流程和具体人工处理的步骤,因为偷懒我这里就不提供了,因为我也是画着画着就没有弄了。

编写伪代码

在vscode上编写具体的流程伪代码

编写正式的代码

按照自己的思路,确定好变量、常量、具体的处理流程等等,按照伪代码进行一步一步的代码编写。

最终的代码

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/unidoc/unioffice/document"
	"github.com/unidoc/unioffice/measurement"
	"github.com/unidoc/unioffice/schema/soo/wml"
	"github.com/unidoc/unioffice/spreadsheet"
)
type biaozhi struct {
	yeMeiTime        string // 页眉的时间编号
	neiRouTime       string // 内容的时间格式
	ipaddr           string // 其实就是告警对象:主要填IP
	tiaomushu        string // 告警的条目数
	gaojingxinxi     string // 告警信息:告警描述
	xitong           string // 被攻击的系统名称
	danwei           string // 被攻击的单位
	chuzhijianyi     string // 处置建议
	lujing           string // 告警中的路径,病毒存在的路径、webshell的路径等
	shijianmingcheng string // 事件名称
	yjShiJianLeiXing string // 应急事件报告中特有的事件类型
	shijianjibie     string // 事件的级别
	loudongmingcheng string // 漏洞预警:漏洞名称
	yxBanBen         string // 漏洞预警:影响版本
	wenjianmingcheng string // 另存为文件的名称
	fengxianmiaoshu  string // 风险验证描述
}

var (
	// Baogao 要打开的报告类型
	Baogao string
	// SaveFile 要打开的报告类型
	SaveFile string
	dataList biaozhi
)

// 1.判断输出的是什么通告
func tonggao() {
	a, _ := spreadsheet.Open("素材.xlsx")
	excel, err := a.GetSheet("需要填写的资料")
	if err != nil {
		log.Fatalf("excel打开表错误,错误信息: %s", err)
	}
	defer a.Close()

	SaveFile = excel.Cell("B1").GetString() // 看是什么类型的报告获取字符串。
	switch SaveFile {
	case "可疑行为":
		Baogao = "可疑行为预警通告.docx"
	case "风险预警":
		Baogao = "安全风险预警通告.docx"
	case "应急预警":
		Baogao = "安全事件应急通告.docx"
	case "漏洞预警":
		Baogao = "安全漏洞预警通告.docx"
	default:
		log.Println("请检查(素材.xlsx)文件(需要填写的资料)表中报告类型是否正确!")
	}

	// 获取相关的数据
	dataList.shijianmingcheng = excel.Cell("B2").GetString()  // 风险预警:获取事件名称
	dataList.shijianjibie = excel.Cell("B3").GetString()      // 所有预警:获取事件级别
	dataList.ipaddr = excel.Cell("B4").GetString()            // 应急预警:业务IP地址
	dataList.lujing = excel.Cell("B5").GetString()            // 获取告警路径;
	dataList.tiaomushu = excel.Cell("B6").GetString()         // 获取告警路径;
	dataList.gaojingxinxi = excel.Cell("B7").GetString()      // 所有预警:告警描述
	dataList.chuzhijianyi = excel.Cell("B8").GetString()      // 所有预警:获取处置建议
	dataList.yjShiJianLeiXing = excel.Cell("B9").GetString()  // 应急预警:事件类型
	dataList.loudongmingcheng = excel.Cell("B10").GetString() // 漏洞预警:漏洞名称
	dataList.yxBanBen = excel.Cell("B11").GetString()         // 漏洞预警:影响版本
	dataList.xitong = excel.Cell("B12").GetString()           // 风险预警:业务系统名称
	dataList.danwei = excel.Cell("B13").GetString()           // 风险预警:业务单位名称
	dataList.fengxianmiaoshu = excel.Cell("B14").GetString()  // 风险预警:风险验证描述
}

// 2.处理并输出报告
func baogao() {

	// 打开一个已有格式的文档
	doc, err := document.Open(Baogao)
	if err != nil {
		log.Fatalf("打开word文档错误,错误信息: %s", err)
	}

	// 设置页眉
	hdr := doc.AddHeader()
	para := hdr.AddParagraph()
	para.Properties().AddTabStop(8*measurement.Inch, wml.ST_TabJcRight, wml.ST_TabTlcUnset)
	run := para.AddRun()
	run.AddTab()
	run.AddText("编号:-" + dataList.yeMeiTime)
	run.Properties().SetBold(true)
	run.Properties().SetSize(8)
	// run.Properties().SetColor(color.Black)
	doc.BodySection().SetHeader(hdr, wml.ST_HdrFtrUnset)
	// 页眉设置完毕

	for _, p := range doc.Paragraphs() { // 遍历所有段落
		for _, r := range p.Runs() { // 遍历相同格式的段落
			if SaveFile == "应急预警" {
				switch r.Text() {
				case "事件名称:":
					r.ClearContent()
					r.AddText("事件名称:" + dataList.shijianmingcheng)
				case "事件类型:":
					r.ClearContent()
					r.AddText("事件类型:" + dataList.yjShiJianLeiXing)
				case "事件级别:":
					r.ClearContent()
					r.AddText("事件级别:" + dataList.shijianjibie)
				case "告警对象:":
					r.ClearContent()
					r.AddText("告警对象:" + dataList.ipaddr)
				case "所属系统:":
					r.ClearContent()
					r.AddText("所属系统:" + dataList.xitong + "系统,隶属于" + dataList.danwei)
				case "告警内容:":
					r.ClearContent()
					r.AddText("告警内容:" + dataList.gaojingxinxi)
				case "路径":
					r.ClearContent()
					r.AddText(dataList.lujing)
				case "处置建议哦":
					r.ClearContent()
					r.AddText(dataList.chuzhijianyi)
				case "应急描述":
					r.ClearContent()
					r.AddText(dataList.neiRouTime + ",监控平台动态智能监控发现业务(IP:" + dataList.ipaddr + ")产生" + dataList.tiaomushu + "条“" + dataList.shijianmingcheng + "”日志告警信息。经资产确认,该主机为“" + dataList.xitong + "系统,隶属于" + dataList.danwei + "。")
				}
			} else {
				switch r.Text() {
				case "漏洞名称哦":
					r.ClearContent()
					r.AddText(dataList.loudongmingcheng) // 漏洞名称
				case "影响版本哦":
					r.ClearContent()
					r.AddText(dataList.yxBanBen) // 影响版本
				case "风险描述哦":
					r.ClearContent()
					r.AddText(dataList.gaojingxinxi) // 风险描述
				case "事件名称哦":
					r.ClearContent()
					r.AddText(dataList.shijianmingcheng)
				case "风险等级哦":
					r.ClearContent()
					r.AddText(dataList.shijianjibie) //风险等级
				case "疑点1":
					r.ClearContent()
					r.AddText(dataList.gaojingxinxi)
				case "路径":
					r.ClearContent()
					r.AddText(dataList.lujing)
				case "处置建议哦":
					r.ClearContent()
					r.AddText(dataList.chuzhijianyi)
				case "业务所属":
					yewu := "经资产确认,该主机为" + dataList.xitong + "系统,隶属于" + dataList.danwei
					r.ClearContent()
					r.AddText(yewu)
				case "风险验证描述":
					r.ClearContent()
					r.AddText(dataList.fengxianmiaoshu)
				default:
					fmt.Println("not modifying", r.Text())
				}
			}
		}
	}

	switch SaveFile {
	case "可疑行为":
		dataList.wenjianmingcheng = "【" + dataList.shijianmingcheng + "】" + "可疑行为预警通告" + dataList.yeMeiTime + ".docx"
	case "风险预警":
		dataList.wenjianmingcheng = "【" + dataList.shijianmingcheng + "】" + "安全风险预警通告" + dataList.yeMeiTime + ".docx"
	case "应急预警":
		dataList.wenjianmingcheng = "【" + dataList.shijianmingcheng + "】" + "安全事件应急通告" + dataList.yeMeiTime + ".docx"
	case "漏洞预警":
		dataList.wenjianmingcheng = "【" + dataList.loudongmingcheng + "】" + "安全漏洞预警通告" + dataList.yeMeiTime + ".docx"
	}
	err = doc.SaveToFile(dataList.wenjianmingcheng)
	if err != nil {
		log.Fatalln("文件保存错误:", err)
	}
}

func main() {
	// 获取符合我们格式的时间。
	dataList.neiRouTime = time.Now().Format("2006年01月02日15时04分")
	dataList.yeMeiTime = time.Now().Format("200601021504")

	tonggao()

	baogao()

}

问题

1.页眉其实有排版和字体问题,可惜时间太短用了一天时间写了这个程序,因为是新手所以大神勿喷。
2.word读取的时候存在问题,需要docx清除所有格式才能如你所愿地识别出来字段,举个有问题的例子:

以下是word文档的两个段:
	恶意告警
	攻击事件经过分析还存在其他问题,1:端口继续对外开放;2:漏洞未被修复。

如果这个文档有自己的格式如:仿宋字体;加粗;四号等等。。。
那么识别就会出现问题,识别结果如下:

恶意
告警
攻击事件
经过
分析还存在其它问题,
1
:端口继续对外开放;2:漏洞未被修复。

那么识别出来的字段就会有问题,不能按照我们关键字的方式进行识别并替换。
如我想识别出恶意告警,作为关键字,再替换为我想要的写的内容。但是这样的情况下就无法做了。

3.excel读出数据之后,可以读取成切片,变成数组,通过unioffice这个库的AddBreak()函数进行换行,继续写入内容。示例代码如下:

for _, t := range dataList.chuzhijianyi { //重复执行
	r.AddText(t) //写入内容
	r.AddBreak() //换行
}

你可能感兴趣的:(golang)