文档章节

VC输出word——读取xml模板并存储为多页(加入分页符)

o
 osc_z1hvg4cu
发布于 2018/04/24 08:23
字数 1284
阅读 0
收藏 0

精选30+云产品,助力企业轻松上云!>>>

项目中遇到一个新需求,要输出一些数据到word表格,而数据量不确定,超过一页的话需要分割输出多页word。师弟对此表示摇头,没办法,我只好抽时间亲自上阵。

OK,首先要搞明白xml里面word是如何进行分页的。

我在word里面新建了两个文档,一个只有一页,另一个有两页,中间有一个分页符和一个换行符(作用后面再说),像下面两张图一样:

 

然后将两张图另存为XML模板,这里我导出的是03版本的,其中第一个文档,找到其<body>到</body>之间的字符:

<w:body>
<wx:sect>
////////////////////////////////////////1(该行是注释)
<w:p wsp:rsidR="00AA0B17" wsp:rsidRPr="00CB3957" wsp:rsidRDefault="0053415C">
<w:pPr>
<w:rPr>
<w:sz w:val="240"/><w:sz-cs w:val="84"/>
</w:rPr>
</w:pPr>
<w:r wsp:rsidRPr="00CB3957">
<w:rPr>
<w:rFonts w:hint="fareast"/><wx:font wx:val="宋体"/><w:sz w:val="240"/><w:sz-cs w:val="84"/>
</w:rPr>
<w:t>第一页</w:t>
</w:r>
</w:p>
////////////////////////////////////////2(该行是注释)
<w:sectPr wsp:rsidR="00AA0B17" wsp:rsidRPr="00CB3957">
<w:pgSz w:w="11906" w:h="16838"/><w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/><w:cols w:space="425"/><w:docGrid w:type="lines" w:line-pitch="312"/>
</w:sectPr>
</wx:sect>
</w:body>
View Code

然后对比第二个文档的XML

 1 <w:body>
 2 <wx:sect>
 3 //////////////////////////////////3
 4 <w:p wsp:rsidR="00704431" wsp:rsidRPr="0024060F" wsp:rsidRDefault="00704431" wsp:rsidP="00704431">
 5 <w:pPr>
 6 <w:rPr>
 7 <w:sz w:val="144"/><w:sz-cs w:val="84"/>
 8 </w:rPr>
 9 </w:pPr>
10 <w:r wsp:rsidRPr="0024060F">
11 <w:rPr>
12 <w:rFonts w:hint="fareast"/><wx:font wx:val="宋体"/>
13 <w:sz w:val="96"/><w:sz-cs w:val="84"/>
14 </w:rPr>
15 <w:t>第一页</w:t>
16 </w:r>
17 </w:p>
18 /////////////////////////////////////4
19 <w:p wsp:rsidR="007B1B30" wsp:rsidRDefault="00704431" wsp:rsidP="0024060F">
20 <w:pPr>
21 <w:widowControl/><w:jc w:val="left"/>
22 <w:rPr>
23 <w:rFonts w:hint="fareast"/><w:sz w:val="96"/><w:sz-cs w:val="84"/>
24 </w:rPr>
25 </w:pPr>
26 <w:r wsp:rsidRPr="0024060F">
27 <w:rPr>
28 <w:sz w:val="96"/><w:sz-cs w:val="84"/>
29 </w:rPr>
30 <w:br w:type="page"/>
31 </w:r>
32 </w:p>
33 ////////////////////////////////////5
34 <w:p wsp:rsidR="0080147A" wsp:rsidRPr="0024060F" wsp:rsidRDefault="00704431" wsp:rsidP="0024060F">
35 <w:pPr>
36 <w:widowControl/><w:jc w:val="left"/>
37 <w:rPr>
38 <w:sz w:val="96"/><w:sz-cs w:val="84"/>
39 </w:rPr>
40 </w:pPr>
41 <w:r wsp:rsidRPr="0024060F">
42 <w:rPr>
43 <w:rFonts w:hint="fareast"/><wx:font wx:val="宋体"/><w:sz w:val="96"/><w:sz-cs w:val="84"/>
44 </w:rPr>
45 <w:t>第二页</w:t>
46 </w:r>
47 </w:p>
48 //////////////////////////////////////6
49 <w:sectPr wsp:rsidR="0080147A" wsp:rsidRPr="0024060F" wsp:rsidSect="00CE1B00">
50 <w:pgSz w:w="11906" w:h="16838"/><w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/><w:cols w:space="425"/><w:docGrid w:type="lines" w:line-pitch="312"/>
51 </w:sectPr>
52 </wx:sect>
53 </w:body>
View Code

可以看出,第一页和第二页不同的部分在于多了4-5和5-6中间的部分,而5-6部分与第一页其实是类似的,因此换行符就是4-5中间部分代码:

 1 <w:p wsp:rsidR="007B1B30" wsp:rsidRDefault="00704431" wsp:rsidP="0024060F">
 2  <w:pPr>
 3   <w:widowControl/><w:jc w:val="left"/>
 4   <w:rPr>
 5    <w:rFonts w:hint="fareast"/><w:sz w:val="96"/><w:sz-cs w:val="84"/>
 6    </w:rPr>
 7  </w:pPr>
 8  <w:r wsp:rsidRPr="0024060F">
 9   <w:rPr>
10    <w:sz w:val="96"/><w:sz-cs w:val="84"/>
11   </w:rPr>
12   <w:br w:type="page"/>
13  </w:r>
14 </w:p>
View Code

剩下的事情就简单了,聪明的你肯定知道该怎么从一页的模板生成多页文档了!

我是这么做的:

1.读取xml字符串以后,从主体部分找到并分离该页文档所有内容(1-2):

//找到第一页内容strOnePage,从<wx:sect>后一位到<w:sectPr第一位之间的<w:p到</w:p>的内容(1-2)
//tStr[2]是读取的xml从<w:wordDocument到</w:wordDocument>的所有内容
CString strOnePage(tStr[2]);
int iBegin = strOnePage.Find("<w:sectPr");
strOnePage = strOnePage.Left(iBegin);
int iEnd = strOnePage.Find("<wx:sect>");
iEnd += 8;
strOnePage = strOnePage.Right(strOnePage.GetLength() - iEnd - 1);

2.之后循环所有数据判断该分的页数,找到该内容之后的一个位置作为插入位置(2),然后在第二次循环开始的每次循环中为主体部分在插入位置追加一个分页符字符串(4-5)和一个(1-2),同时替换字符串(1-2)中应该被替换的部分

 1 #define RowInPage 18
 2 //set pages number by iMaxNum, each page can save 18 records
 3 for (int i = 0; i < iMaxNum / RowInPage + 1; i++) {
 4     iBegin = i * RowInPage;
 5     if (iBegin >= iMaxNum) break;
 6     if (0 == i){ 
ReplaceTemplate(tStr[2],outputDatas,iBegin,RowInPage); 7 }else { 8 //find insert position 9 int iInsertPos = tStr[2].Find("<w:sectPr"); 10 //insert a new page 11 //换页符(strSeperator) 12 CString strSeperator("<w:p wsp:rsidR=\"007B1B30\" wsp:rsidRDefault=\"00704431\"><w:pPr><w:widowControl/><w:jc w:val=\"left\"/></w:pPr><w:r><w:br w:type=\"page\"/></w:r></w:p>"); 13 //页面内容(strNextPage) 14 CString strNextPage(strOnePage); 15 //替换每一页模板字符串中的内容,根据自己的需求编写 16 ReplaceTemplate(strNextPage,outputDatas,iBegin,RowInPage); 17 //拼接:换页符(strSeperator)+页面内容(strNextPage) 18 strSeperator += strNextPage; 19 tStr[2].Insert(iInsertPos,strSeperator); 20 } 21 }

至此你就可以实现自己的多页文档了,上一下我实现的效果图:

本次内容结束,胖友再见!

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

自从尝了 Rust,Java 突然不香了

Rust 是软件行业中相对而言比较新的一门编程语言,如果从语法上来比较,该语言与 C++ 其实非常类似,但从另一方面而言,Rust 能更高效地提供许多功能来保证性能和安全。而且,Rust 还能在无需...

osc_k3vwonkw
5分钟前
0
0
Java 高级 面试题 及 参考答案

一、面试题基础总结 1、 JVM结构原理、GC工作机制详解 答:具体参照:JVM结构、GC工作机制详解 ,说到GC,记住两点:1、GC是负责回收所有无任何引用对象的内存空间。 注意:垃圾回收回收的是无...

FH-Admin
5分钟前
9
0
机器学习中的AUC-ROC曲线

作者|ANIRUDDHA BHANDARI 编译|VK 来源|Analytics Vidhya AUC-ROC曲线 你已经建立了你的机器学习模型-那么接下来呢?你需要对它进行评估,并验证它有多好(或有多坏),这样你就可以决定是否...

osc_bg8v9gvf
7分钟前
0
0
音视频(消息)应用场景 :连麦交友例子

实现一个小例子: 效果类似唱吧APP里的 连麦交友功能,音视频,IM 及音视频 SDK参考融云服务商。 没有印象的可以搜索 ’连麦’ 关键字在 应用商店下载一款 连麦的软件 体验下 业务方面的需求...

T型人才追梦者
8分钟前
4
0
逛淘宝天猫想到SSO单点登录

我的原文地址:https://mp.weixin.qq.com/s/77xukPDlgkKnYpwu4LrqaA

osc_yy65eb2q
8分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部