使用c++批量生成docx文档
Posted 2016bits
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用c++批量生成docx文档相关的知识,希望对你有一定的参考价值。
一、需求说明
能够根据模板批量生成docx文档。具体而言,使用c++读取数据(笔者为了简单,使用的是存储在txt中的数据),然后根据模板批量生成docx文档
二、实验准备
1、准备数据:
3
张三
班级 一班
语文 80
数学 70
英语 60
李四
班级 二班
语文 50
数学 10
英语 20
王五
班级 二班
语文 90
数学 100
英语 95
将数据保存为data.txt
2、准备模板:
在指定位置添加书签:
笔者在建立书签时,在两个地方使用相同的书签时在第一个得分无法显示书签,目前还不知道具体原因,所以使用两个不同的书签(name和name1)
将数据保存为template.doc
3、准备vs环境:
使用的是vs2017社区版
使用MFC生成docx文档参考:https://www.jianshu.com/p/a5063628a65a
先安装MFC环境:
打开vs,新建项目:
导入word类库:项目-》类向导-》添加类(下拉框中“类型库中的MFC类”)-》选择“从文件中添加类”,然后从office的安装目录(office的默认路径如下)中找到MSWORD.OLB
然后选择接口:
_Application, _Document, Bookmark, Bookmarks, Cell, Cells, Column, Columns, Documents, Range, Row, Rows, Selection, Table, Tables
对每个接口类,修改一下生成文件位置
然后点击“完成”
在生成的头文件.h中将导入的MSWORD.OLB注释掉:
然后在pch.h文件中添加头文件:
初始化:在自己的MFC项目的.cpp文件中找到XXXApp::InitInstance()中添加以下代码:
然后在MFC项目中添加“生成”按钮,双击按钮,在按钮的点击事件中添加响应事件代码
三、代码实现
写具体的实现代码之前,在ReadWordDlg.h中引入需要使用的头文件,特别注意这个引入头文件的位置,否则会出现交叉引用从而报类似”int类型...“这样的错
首先建立保存数据的结构体:
typedef struct{
char name[20];
char clas[20];
int language;
int math;
int english;
}Stu;
Stu stu[10];
从data.txt中读取数据存入结构体数组:
int readdata(string path)
{
ifstream file(path, ios::in);
if (!file) {//打开文件失败
AfxMessageBox(_T("打开文件失败!"));
return 0;
}
int n;
file >> n;
for (int i = 0; i < n; i++) {
file >> stu[i].name;
char str[20] = "";
file >> str >> stu[i].clas;
file >> str >> stu[i].language;
file >> str >> stu[i].math;
file >> str >> stu[i].english;
}
file.close();
return n;
}
然后将读取的数据批量生成docx文档:
void CReadWordDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
COleVariant covzZero((short)0),
covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR),
covDocxType((short)0),
start_line, end_line,
dot(_T("D:\\\\code\\\\c\\\\ReadWord\\\\template.dot"));
int n = readdata("D:\\\\code\\\\c\\\\ReadWord\\\\data.txt");
for (int i = 0; i < n; i++) {
CApplication wordApp;
CDocuments docs;
CDocument0 docx;
CBookmarks bookmarks;
CBookmark0 bookmark;
CRange range;
CCell cell;
if (!wordApp.CreateDispatch(_T("Word.Application")))
{
AfxMessageBox(_T("本机没有安装word产品!"));
return;
}
//locale::global(locale(""));
wordApp.put_Visible(FALSE);
CString wordVersion = wordApp.get_Version();
docs = wordApp.get_Documents();
docx = docs.Add(dot, covOptional, covOptional, covOptional);
bookmarks = docx.get_Bookmarks();
bookmark = bookmarks.Item(&_variant_t(_T("name1")));
range = bookmark.get_Range();
range.put_Text(convert(stu[i].name));
bookmark = bookmarks.Item(&_variant_t(_T("class")));
range = bookmark.get_Range();
range.put_Text(convert(stu[i].clas));
bookmark = bookmarks.Item(&_variant_t(_T("name")));
range = bookmark.get_Range();
range.put_Text(convert(stu[i].name));
bookmark = bookmarks.Item(&_variant_t(_T("language")));
range = bookmark.get_Range();
CString str_lan;
str_lan.Format(_T("%d"), stu[i].language);
range.put_Text(str_lan);
bookmark = bookmarks.Item(&_variant_t(_T("math")));
range = bookmark.get_Range();
CString str_math;
str_math.Format(_T("%d"), stu[i].math);
range.put_Text(str_math);
bookmark = bookmarks.Item(&_variant_t(_T("English")));
range = bookmark.get_Range();
CString str_en;
str_en.Format(_T("%d"), stu[i].english);
range.put_Text(str_en);
CString strSavePath = _T("D:\\\\code\\\\c\\\\ReadWord\\\\");
strSavePath += convert(stu[i].name);
strSavePath += _T("的成绩单.docx");
docx.SaveAs(COleVariant(strSavePath), covOptional, covOptional, covOptional, covOptional,
covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional,
covOptional, covOptional, covOptional, covOptional);
//退出word应用
docx.Close(covFalse, covOptional, covOptional);
wordApp.Quit(covOptional, covOptional, covOptional);
range.ReleaseDispatch();
bookmarks.ReleaseDispatch();
wordApp.ReleaseDispatch();
}
AfxMessageBox(_T("文档生成成功!"));
}
期间遇到中文字符的处理问题,参考https://blog.csdn.net/weixin_43794736/article/details/116589122
四、实验结果
文件夹中:
样例文档:
以上是关于使用c++批量生成docx文档的主要内容,如果未能解决你的问题,请参考以下文章