├── README.md └── report ├── Award_certificate.m ├── Built-in_Style_English_of_Word.pdf ├── Gradegen.m ├── README.md ├── SchoolReport.m ├── demo1.m ├── demo2.m ├── demo3.m ├── jiangzhuang.png ├── myPlot_img.png ├── mytemplate.dotx ├── rptgen.pdf ├── schoolreport.png ├── 成绩.xlsx ├── 成绩单.docx └── 批量生成奖状.docx /README.md: -------------------------------------------------------------------------------- 1 | # reportgen 2 | > 本文将介绍Matlab的一个实用技巧。一键生成Word版本的报告。Matlab之前都是通过调用COM接口来实现的,类似于VBA,虽然可做的事情很多,但并不适合一般的童鞋。 3 | 4 | ## 1. 自动化报告 5 | 6 | 测试平台: MATLAB 2015b 7 | 8 | 先来看一个最简单的例子(demo1.m) 9 | 10 | ```Matlab 11 | % demo1.m 12 | import mlreportgen.dom.*; 13 | d = Document('demo1','docx'); 14 | open(d); 15 | append(d,'hello world!'); 16 | close(d); 17 | rptview(d.OutputPath); 18 | ``` 19 | 20 | ```Matlab 21 | import mlreportgen.dom.*; 22 | ``` 23 | 第一行是将所需要的类和函数导入工作空间。这里我们最常用的类就是Document. 24 | ```Matlab 25 | d = Document('test','docx'); 26 | open(d); 27 | ``` 28 | 在第二、三行中我们新建一个文档,其中文件类型`docx`可以替换成`html`或者`pdf`. Document类的相关属性可以通过命令查看 (doc mlreportgen.dom.Document) 29 | ```Matlab 30 | append(d,'hello world!'); 31 | ``` 32 | 在第四行我们给文档添加了一句经典的话,我们还可以自定义它们的样式。比如加粗、斜体、改成蓝色、字体大小等等。 33 | ```Matlab 34 | % 替换上面的一行代码 35 | p=Text('hello world'); 36 | p.Style={Bold(true),FontSize('16pt'),Color('blue')}; 37 | p.Strike='double'; 38 | append(d,p) 39 | ``` 40 | 这里出现了第一个文档类:`Text`,即文本。Matlab提供了很多可调节的属性,如下表。修改起来也很方便,如要把文本改为斜体,则添加:`p.Italic=1;`即可。 41 | 42 | | `Text`的属性 | 取值 | 备注 | 43 | | :---- |:----| :---| 44 | |Bold | true/false | 加粗| 45 | |Color | str('red'、'blue'等) |颜色| 46 | |Italic | true/false | 斜体| 47 | |BackgroundColor | str| 背景色| 48 | |Underline| str('single'、'dotdash'等)| 下划线| 49 | |FontFamilyName| str | 字体| 50 | |FontSize| str('12pt')| 字体大小| 51 | |Strike| str| 删除线| 52 | |StyleName| str| 模板中的样式名| 53 | 54 | 55 | 接下来我们将生成一个更复杂的文档。首先想想一个word文档一班都有哪些元素。MATLAB提供了很多(下面的表格仅列出了部分)。本文主要介绍其中的五个:页面设置、标题、段落、表格、图片。 56 | 57 | | 属性 | 含义 | 58 | | :-------------: | :--------| 59 | |CustomAttribute | Custom element attribute| 60 | |CustomElement | Custom element of a document| 61 | |CustomText | Plain text to be appended to a custom element| 62 | |DOCXPageFooter | Page footer for a Word document.| 63 | |DOCXPageHdrFtr | Page Base class for page header and footer| 64 | |DOCXPageHeader | Page header for a Word document.| 65 | |DOCXPageMargins | Margins of pages in a Word page layout| 66 | |DOCXPageSize | Size, orientation of pages in a Word layout| 67 | |DOCXSection | Page layout section of a Word document| 68 | |**Document** | Create a dom document| 69 | |ExternalLink | Create a hyperlink to an external target| 70 | |Form | Defines a form| 71 | |FormalTable | Create a formal table| 72 | |Group | Group of document objects| 73 | |Heading | Create a heading paragraph.| 74 | |HorizontalRule | Create a horizontal rule.| 75 | |**Image** | Create an image to be included in a report.| 76 | |ImageArea | Defines an image area as a hyperlink| 77 | |InternalLink | Create a hyperlink to a target in this| 78 | |LinkTarget | Create a target for a hyperlink.| 79 | |ListItem | Item in a list| 80 | |Node | Defines a document node| 81 | |Object | Defines a document object| 82 | |OrderedList | Ordered (numbered) list| 83 | |Paragraph | Create a formatted block of text, i.e., a paragraph.| 84 | |**Table** | Create a table.| 85 | |TableColSpecGroup| Defines style of a group of table columns| 86 | |TableEntry| Create a table Entry| 87 | |TableRow | Creates a table row| 88 | |Template| Create a template for a document| 89 | |**Text**| Create a text object | 90 | 91 | 接下来我们做一个完整的模板。首先新建空白文档。 92 | 93 | ```Matlab 94 | % demo2.m 95 | import mlreportgen.dom.*; 96 | d=Document('demo2','docx'); 97 | open(d); 98 | ``` 99 | 100 | ### 1.1 页面 101 | 102 | 页面设置包括页面大小('A4'等)、页面方向、页边距. 103 | 104 | ```Matlab 105 | % 页面设置 106 | s = d.CurrentDOCXSection; 107 | s.PageSize.Orientation ='landscape'; % portrait(default) 108 | s.PageSize.Height = '8.5in'; 109 | s.PageSize.Width = '11in'; 110 | s.PageMargins.Left = '3.0cm'; 111 | s.PageMargins.Right = '3.0cm'; 112 | s.PageMargins.Top = '2.5cm'; 113 | s.PageMargins.Bottom = '2.5cm'; 114 | % 中文字体样式设置 115 | heiti=FontFamily; 116 | heiti.FamilyName='Arial'; 117 | heiti.EastAsiaFamilyName='黑体'; 118 | songti=FontFamily; 119 | songti.FamilyName='Arial'; 120 | songti.EastAsiaFamilyName='宋体'; 121 | ``` 122 | 123 | ### 1.2 标题 124 | 标题的初始格式由模板中自带的标题样式决定,当然也可以自己修改。 125 | ```Matlab 126 | %% 标题 127 | p=Heading(1,'Matlab 自动化报告模板');% 一级标题 128 | %p.Color='red'; 129 | %p.HAlign='center'; 130 | p.Style={heiti,Color('red'),HAlign('center')}; 131 | append(d,p); 132 | ``` 133 | 134 | ### 1.3 段落 135 | 136 | 与文本不同,段落除下文本的属性外,还有边距、对齐、首行缩进、行间距、段前、段后等属性需要调节。在下面的代码框中,FirstLineIndent代表首行缩进的宽度,LineSpacing代表行间距,OuterMargin代表边距。在这里我们还引入了一个新的类:ExternalLink(外部链接),当然Matlab也提供文档内部链接:InternalLink. 137 | 138 | ```Matlab 139 | %% 段落 140 | append(d,Heading(2,'一、段落模板')); 141 | s='这里是段落。'; 142 | s=repmat(s,[1,12]); 143 | p = Paragraph(s); 144 | % 中文字体样式自定义 145 | p.Style={songti,Color('blue'),... 146 | LineSpacing(1.5),... 147 | OuterMargin('10pt','0pt','0pt','10pt')}; 148 | p1=Text('下划线。');%同段落差不多. 149 | p1.Underline='single'; 150 | p1.Color='red'; 151 | append(p,p1); 152 | append(p,s); 153 | p2=ExternalLink('http://github.com/gasongjian/', '超链接'); 154 | append(p,p2); 155 | p.FontSize='14pt'; 156 | p.FirstLineIndent='28pt';%这里差不多就是2个字符大小 157 | append(d,p); 158 | ``` 159 | 160 | ### 1.4 简易表格 161 | 162 | Matlab 支持直接从数组矩阵和元胞矩阵建立表格。如`t=Table(magic(5))`或者 163 | `t=Table(cell(5))`. 也可以利用TableRow一行一行添加。一个单元格可以填充的元素很多(文本、图像等),所以可调节的就是表格的边框、单元格的大小、对齐等。本文给出一个简易的例子和一个复杂的例子。一件很遗憾的事就是不能合并单元格。当写完demo2后,本文还将提供一种更为简便的方式。 164 | 165 | ```Matlab 166 | %% 简易表格 167 | append(d,Heading(2,'二、简单表格')); 168 | t={'志明','语文','数学','英语'; ... 169 | '成绩','70','98','89'; ... 170 | '等级','B','A','A'}; 171 | p=Table(t); 172 | 173 | % 格式化单元格中的段落 174 | for ii=1:p.NRows 175 | for jj=1:p.NCols 176 | t=entry(p,ii,jj); 177 | t.Children(1).Style={songti,... 178 | Color('green'),... 179 | FontSize('12pt'),... 180 | LineSpacing(1.0),... 181 | OuterMargin('0pt','0pt','0pt','0pt')}; 182 | end 183 | end 184 | 185 | p.Style = {Border('single','blue','3px'), ... 186 | ColSep('single','blue','1px'), ... 187 | RowSep('single','blue','1px')}; 188 | 189 | p.Width = '50%'; 190 | p.HAlign='center';% 居中对齐 191 | p.TableEntriesHAlign='center'; 192 | p.TableEntriesVAlign='middle'; 193 | append(d,p); 194 | ``` 195 | 196 | ### 1.5 复杂表格 197 | 198 | ```Matlab 199 | %% 复杂表格 200 | append(d,Heading(2,'三、复杂表格')); 201 | q = Table(5); 202 | q.Border = 'single'; 203 | q.ColSep = 'single'; 204 | q.RowSep = 'single'; 205 | 206 | row = TableRow; 207 | te = TableEntry('算法名称'); 208 | te.RowSpan = 2; 209 | append(row, te); 210 | 211 | te = TableEntry('第一类'); 212 | te.ColSpan = 2; 213 | %te.Border = 'single'; 214 | append(row, te); 215 | te = TableEntry('第二类'); 216 | te.ColSpan = 2; 217 | %te.Border = 'single'; 218 | append(row, te); 219 | append(q,row); 220 | 221 | % 第二行 222 | row=TableRow; 223 | append(row,TableEntry('T1')); 224 | append(row,TableEntry('T2')); 225 | append(row,TableEntry('T3')); 226 | append(row,TableEntry('T4')); 227 | append(q,row); 228 | 229 | % 其他行 230 | t=TableRow; 231 | append(t,TableEntry('条目')); 232 | for i=1:4 233 | append(t,TableEntry(' ')); 234 | end 235 | append(q,t); 236 | append(q,clone(t)); 237 | append(q,clone(t)); 238 | append(q,clone(t)); 239 | q.TableEntriesStyle={Width('80'),Height('40')}; 240 | q.Style = {Border('single','green','3px'), ... 241 | ColSep('single','green','1px'), ... 242 | RowSep('single','green','1px')}; 243 | 244 | q.HAlign='center';% 居中对齐 245 | q.TableEntriesHAlign='center'; 246 | q.TableEntriesVAlign='middle'; 247 | append(d,q); 248 | ``` 249 | 250 | ### 1.6 图片 251 | ```Matlab 252 | %% 插入图片 253 | append(d,Heading(2,'四、图片模板')); 254 | p1 = Image('myPlot_img.png'); 255 | % ScaleToFit是为了使图片大小适应页面,也可以换成下方的自定义大小设置 256 | %p1.Style={HAlign('center'),ScaleToFit(1)}; 257 | p1.Style={HAlign('center'),Width('600px'),Height('400px')}; 258 | append(d,p1); 259 | 260 | close(d); 261 | rptview(d.OutputPath); 262 | ``` 263 | 264 | 作为一个懒人,我希望写得更极致一点, 即我只想关注内容而忽略这些格式。这时候我们可以利用模板来实现这一切,把所需要的样式都存在模板里。事实上新建Word文档都是基于模板建立的,Matlab也是。通过在模板里修改默认样式或者新建样式,我们可以极大简化上述代码,从而使得上述工作不那么像编程。 265 | 266 | ### 1.7 巧用模板来简化代码 267 | 268 | ```Matlab 269 | % demo3.m 270 | % 利用模板中的样式来生成报告 271 | % 如果是中文版Word,自带样式名称请参见目录下的pdf文档 272 | 273 | import mlreportgen.dom.* 274 | % 模板文件 mytemplate.dotx 在文末会附下载链接 275 | d=Document('demo3','docx',fullfile(pwd,'mytemplate')); 276 | open(d); 277 | %% 标题 278 | p=Paragraph('成绩报告单','Heading 1'); 279 | append(d,p); 280 | %% 文字段落(doc mlreportgen.dom.Paragraph) 281 | append(d,Heading(2,'一、段落模板')); 282 | s='这里是段落'; 283 | s=repmat(s,[1,30]); 284 | p = Paragraph(s,'mypara1');%自定义段落样式 285 | append(d,p); 286 | %% 添加空的段落行 287 | for i=1:8 288 | append(d,' '); 289 | end 290 | %% 插入表格 291 | append(d,Heading(2,'二、表格模板')); 292 | t={'姓名','语文','数学','英语'; ... 293 | '成绩','70','94','82'; ... 294 | '等级','C','A','B'}; 295 | p=Table(t,'mytable1');% 自定义表格样式 296 | append(d,p); 297 | close(d); 298 | rptview(d.OutputPath); 299 | 300 | ``` 301 | 302 | 到这一个完整的模板就差不多了,还有一些新的类需要读者自己去探索。 接下来才是本文的正题,我们来玩一点好玩的事情。 303 | 304 | 305 | 306 | 307 | ## 2. 批量生成成绩单 308 | 309 | >数据集和目标: 310 | 1. 班级所有人的成绩表(成绩.xlsx):姓名、语文、数学、总分; 311 | 2. 给每个同学生一张成绩单,其中只有自己一个人的分数和相对应的等级。 312 | 313 | 314 | ```Matlab 315 | % SchoolReport.m 316 | % n=学生人数 317 | % 为使得程序可读性加强,我们需要格式化成绩单 318 | % 1. 第一行格式:姓名,各个学科,总分 319 | % 2. 只有学生成绩,没有其他很杂的信息。 320 | % 3. 部分成绩若空缺,请不要用数字填充,可以空着或者文字(缺考)填充。 321 | 322 | %% 数据导入 323 | filename='成绩.xlsx'; 324 | savename='成绩单'; 325 | [score,textdata]=xlsread(filename); 326 | m=3; %学科数 327 | n=size(score,1);% 学生人数 328 | name=textdata(2:n+1,1); 329 | mean_score=mean(score,'omitnan'); 330 | max_score=max(score,[],'omitnan'); 331 | grade=Gradegen(score); %Gradegen是自定义函数,生成各个同学的等级 332 | 333 | %模板,实考对应变量score,等级对应变量grade 334 | template=cell(5,m+1); 335 | template(1,1:m+1)={'姓名','语文','数学','总分'}; 336 | template(2:5,1)={'实考成绩';'平均成绩';'最高成绩';'等级'}; 337 | 338 | %% 相关接口 339 | import mlreportgen.dom.*; 340 | d = Document(savename,'docx',fullfile(pwd,'mytemplate')); 341 | open(d); 342 | 343 | %% 开始生成word成绩单列表 344 | 345 | % 添加分割线 346 | hr = HorizontalRule(); 347 | hr.Style={Border('dotdash','blue','2px')}; 348 | append(d,hr); 349 | % n是学生人数,m是学科数 350 | for i=1:n 351 | % 填充表格 352 | template{1,1}=name{i}; 353 | for jj=2:m+1 354 | s=score(i,jj-1); 355 | if isnan(s) 356 | s='缺考'; 357 | else 358 | s=num2str(s); 359 | end 360 | template{2,jj}=s;% 具体分数 361 | template{3,jj}=sprintf('%4.2f',mean_score(jj-1));%学科平均分数 362 | template{4,jj}=num2str(max_score(jj-1));%学科最高分数 363 | template{5,jj}=grade{i,jj-1};% 等级 364 | end 365 | 366 | q=Table(template,'mytable2'); 367 | q.TableEntriesStyle={Width('100'),Height('50')}; 368 | append(d,q); 369 | append(d,clone(hr)); 370 | end 371 | close(d); 372 | rptview(d.OutputPath); 373 | ``` 374 | 375 | 成果预览: 376 | 377 | ![schoolreport.png](schoolreport.png) 378 | 379 | 除此之外,本文还提供了一个批量生成奖状的模板(在Word里也可以通过邮件合并功能实现)供参考。 380 | 381 | 382 | ![jiangzhuang.png](jiangzhuang.png) 383 | 384 | 385 | 386 | 387 | -------------------------------------------------------------------------------- /report/Award_certificate.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/Award_certificate.m -------------------------------------------------------------------------------- /report/Built-in_Style_English_of_Word.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/Built-in_Style_English_of_Word.pdf -------------------------------------------------------------------------------- /report/Gradegen.m: -------------------------------------------------------------------------------- 1 | function G=Gradegen(Score) 2 | [n,m]=size(Score); 3 | Y=sort(Score,'descend'); 4 | A=Y(floor(n/4),:);B=Y(floor(n/2),:);C=Y(floor(n*3/4),:); 5 | G=cell(n,m); 6 | for i=1:n 7 | for j=1:m 8 | if Score(i,j)>=A(j) 9 | G{i,j}='A'; 10 | elseif Score(i,j)>=B(j) 11 | G{i,j}='B'; 12 | elseif Score(i,j)>=C(j) 13 | G{i,j}='C'; 14 | elseif isnan(Score(i,j)) 15 | G{i,j}=' '; 16 | else 17 | G{i,j}='D'; 18 | end 19 | end 20 | end 21 | 22 | -------------------------------------------------------------------------------- /report/README.md: -------------------------------------------------------------------------------- 1 | # reportgen 2 | > 本文将介绍Matlab的一个实用技巧。一键生成Word版本的报告。Matlab之前都是通过调用COM接口来实现的,类似于VBA,虽然可做的事情很多,但并不适合一般的童鞋。 3 | 4 | ## 1. 自动化报告 5 | 6 | 测试平台: MATLAB 2015b 7 | 8 | 先来看一个最简单的例子(demo1.m) 9 | 10 | ```Matlab 11 | % demo1.m 12 | import mlreportgen.dom.*; 13 | d = Document('demo1','docx'); 14 | open(d); 15 | append(d,'hello world!'); 16 | close(d); 17 | rptview(d.OutputPath); 18 | ``` 19 | 20 | ```Matlab 21 | import mlreportgen.dom.*; 22 | ``` 23 | 第一行是将所需要的类和函数导入工作空间。这里我们最常用的类就是Document. 24 | ```Matlab 25 | d = Document('test','docx'); 26 | open(d); 27 | ``` 28 | 在第二、三行中我们新建一个文档,其中文件类型`docx`可以替换成`html`或者`pdf`. Document类的相关属性可以通过命令查看 (doc mlreportgen.dom.Document) 29 | ```Matlab 30 | append(d,'hello world!'); 31 | ``` 32 | 在第四行我们给文档添加了一句经典的话,我们还可以自定义它们的样式。比如加粗、斜体、改成蓝色、字体大小等等。 33 | ```Matlab 34 | % 替换上面的一行代码 35 | p=Text('hello world'); 36 | p.Style={Bold(true),FontSize('16pt'),Color('blue')}; 37 | p.Strike='double'; 38 | append(d,p) 39 | ``` 40 | 这里出现了第一个文档类:`Text`,即文本。Matlab提供了很多可调节的属性,如下表。修改起来也很方便,如要把文本改为斜体,则添加:`p.Italic=1;`即可。 41 | 42 | | `Text`的属性 | 取值 | 备注 | 43 | | :---- |:----| :---| 44 | |Bold | true/false | 加粗| 45 | |Color | str('red'、'blue'等) |颜色| 46 | |Italic | true/false | 斜体| 47 | |BackgroundColor | str| 背景色| 48 | |Underline| str('single'、'dotdash'等)| 下划线| 49 | |FontFamilyName| str | 字体| 50 | |FontSize| str('12pt')| 字体大小| 51 | |Strike| str| 删除线| 52 | |StyleName| str| 模板中的样式名| 53 | 54 | 55 | 接下来我们将生成一个更复杂的文档。首先想想一个word文档一班都有哪些元素。MATLAB提供了很多(下面的表格仅列出了部分)。本文主要介绍其中的五个:页面设置、标题、段落、表格、图片。 56 | 57 | | 属性 | 含义 | 58 | | :-------------: | :--------| 59 | |CustomAttribute | Custom element attribute| 60 | |CustomElement | Custom element of a document| 61 | |CustomText | Plain text to be appended to a custom element| 62 | |DOCXPageFooter | Page footer for a Word document.| 63 | |DOCXPageHdrFtr | Page Base class for page header and footer| 64 | |DOCXPageHeader | Page header for a Word document.| 65 | |DOCXPageMargins | Margins of pages in a Word page layout| 66 | |DOCXPageSize | Size, orientation of pages in a Word layout| 67 | |DOCXSection | Page layout section of a Word document| 68 | |**Document** | Create a dom document| 69 | |ExternalLink | Create a hyperlink to an external target| 70 | |Form | Defines a form| 71 | |FormalTable | Create a formal table| 72 | |Group | Group of document objects| 73 | |Heading | Create a heading paragraph.| 74 | |HorizontalRule | Create a horizontal rule.| 75 | |**Image** | Create an image to be included in a report.| 76 | |ImageArea | Defines an image area as a hyperlink| 77 | |InternalLink | Create a hyperlink to a target in this| 78 | |LinkTarget | Create a target for a hyperlink.| 79 | |ListItem | Item in a list| 80 | |Node | Defines a document node| 81 | |Object | Defines a document object| 82 | |OrderedList | Ordered (numbered) list| 83 | |Paragraph | Create a formatted block of text, i.e., a paragraph.| 84 | |**Table** | Create a table.| 85 | |TableColSpecGroup| Defines style of a group of table columns| 86 | |TableEntry| Create a table Entry| 87 | |TableRow | Creates a table row| 88 | |Template| Create a template for a document| 89 | |**Text**| Create a text object | 90 | 91 | 接下来我们做一个完整的模板。首先新建空白文档。 92 | 93 | ```Matlab 94 | % demo2.m 95 | import mlreportgen.dom.*; 96 | d=Document('demo2','docx'); 97 | open(d); 98 | ``` 99 | 100 | ### 1.1 页面 101 | 102 | 页面设置包括页面大小('A4'等)、页面方向、页边距. 103 | 104 | ```Matlab 105 | % 页面设置 106 | s = d.CurrentDOCXSection; 107 | s.PageSize.Orientation ='landscape'; % portrait(default) 108 | s.PageSize.Height = '8.5in'; 109 | s.PageSize.Width = '11in'; 110 | s.PageMargins.Left = '3.0cm'; 111 | s.PageMargins.Right = '3.0cm'; 112 | s.PageMargins.Top = '2.5cm'; 113 | s.PageMargins.Bottom = '2.5cm'; 114 | % 中文字体样式设置 115 | heiti=FontFamily; 116 | heiti.FamilyName='Arial'; 117 | heiti.EastAsiaFamilyName='黑体'; 118 | songti=FontFamily; 119 | songti.FamilyName='Arial'; 120 | songti.EastAsiaFamilyName='宋体'; 121 | ``` 122 | 123 | ### 1.2 标题 124 | 标题的初始格式由模板中自带的标题样式决定,当然也可以自己修改。 125 | ```Matlab 126 | %% 标题 127 | p=Heading(1,'Matlab 自动化报告模板');% 一级标题 128 | %p.Color='red'; 129 | %p.HAlign='center'; 130 | p.Style={heiti,Color('red'),HAlign('center')}; 131 | append(d,p); 132 | ``` 133 | 134 | ### 1.3 段落 135 | 136 | 与文本不同,段落除下文本的属性外,还有边距、对齐、首行缩进、行间距、段前、段后等属性需要调节。在下面的代码框中,FirstLineIndent代表首行缩进的宽度,LineSpacing代表行间距,OuterMargin代表边距。在这里我们还引入了一个新的类:ExternalLink(外部链接),当然Matlab也提供文档内部链接:InternalLink. 137 | 138 | ```Matlab 139 | %% 段落 140 | append(d,Heading(2,'一、段落模板')); 141 | s='这里是段落。'; 142 | s=repmat(s,[1,12]); 143 | p = Paragraph(s); 144 | % 中文字体样式自定义 145 | p.Style={songti,Color('blue'),... 146 | LineSpacing(1.5),... 147 | OuterMargin('10pt','0pt','0pt','10pt')}; 148 | p1=Text('下划线。');%同段落差不多. 149 | p1.Underline='single'; 150 | p1.Color='red'; 151 | append(p,p1); 152 | append(p,s); 153 | p2=ExternalLink('http://github.com/gasongjian/', '超链接'); 154 | append(p,p2); 155 | p.FontSize='14pt'; 156 | p.FirstLineIndent='28pt';%这里差不多就是2个字符大小 157 | append(d,p); 158 | ``` 159 | 160 | ### 1.4 简易表格 161 | 162 | Matlab 支持直接从数组矩阵和元胞矩阵建立表格。如`t=Table(magic(5))`或者 163 | `t=Table(cell(5))`. 也可以利用TableRow一行一行添加。一个单元格可以填充的元素很多(文本、图像等),所以可调节的就是表格的边框、单元格的大小、对齐等。本文给出一个简易的例子和一个复杂的例子。一件很遗憾的事就是不能合并单元格。当写完demo2后,本文还将提供一种更为简便的方式。 164 | 165 | ```Matlab 166 | %% 简易表格 167 | append(d,Heading(2,'二、简单表格')); 168 | t={'志明','语文','数学','英语'; ... 169 | '成绩','70','98','89'; ... 170 | '等级','B','A','A'}; 171 | p=Table(t); 172 | 173 | % 格式化单元格中的段落 174 | for ii=1:p.NRows 175 | for jj=1:p.NCols 176 | t=entry(p,ii,jj); 177 | t.Children(1).Style={songti,... 178 | Color('green'),... 179 | FontSize('12pt'),... 180 | LineSpacing(1.0),... 181 | OuterMargin('0pt','0pt','0pt','0pt')}; 182 | end 183 | end 184 | 185 | p.Style = {Border('single','blue','3px'), ... 186 | ColSep('single','blue','1px'), ... 187 | RowSep('single','blue','1px')}; 188 | 189 | p.Width = '50%'; 190 | p.HAlign='center';% 居中对齐 191 | p.TableEntriesHAlign='center'; 192 | p.TableEntriesVAlign='middle'; 193 | append(d,p); 194 | ``` 195 | 196 | ### 1.5 复杂表格 197 | 198 | ```Matlab 199 | %% 复杂表格 200 | append(d,Heading(2,'三、复杂表格')); 201 | q = Table(5); 202 | q.Border = 'single'; 203 | q.ColSep = 'single'; 204 | q.RowSep = 'single'; 205 | 206 | row = TableRow; 207 | te = TableEntry('算法名称'); 208 | te.RowSpan = 2; 209 | append(row, te); 210 | 211 | te = TableEntry('第一类'); 212 | te.ColSpan = 2; 213 | %te.Border = 'single'; 214 | append(row, te); 215 | te = TableEntry('第二类'); 216 | te.ColSpan = 2; 217 | %te.Border = 'single'; 218 | append(row, te); 219 | append(q,row); 220 | 221 | % 第二行 222 | row=TableRow; 223 | append(row,TableEntry('T1')); 224 | append(row,TableEntry('T2')); 225 | append(row,TableEntry('T3')); 226 | append(row,TableEntry('T4')); 227 | append(q,row); 228 | 229 | % 其他行 230 | t=TableRow; 231 | append(t,TableEntry('条目')); 232 | for i=1:4 233 | append(t,TableEntry(' ')); 234 | end 235 | append(q,t); 236 | append(q,clone(t)); 237 | append(q,clone(t)); 238 | append(q,clone(t)); 239 | q.TableEntriesStyle={Width('80'),Height('40')}; 240 | q.Style = {Border('single','green','3px'), ... 241 | ColSep('single','green','1px'), ... 242 | RowSep('single','green','1px')}; 243 | 244 | q.HAlign='center';% 居中对齐 245 | q.TableEntriesHAlign='center'; 246 | q.TableEntriesVAlign='middle'; 247 | append(d,q); 248 | ``` 249 | 250 | ### 1.6 图片 251 | ```Matlab 252 | %% 插入图片 253 | append(d,Heading(2,'四、图片模板')); 254 | p1 = Image('myPlot_img.png'); 255 | % ScaleToFit是为了使图片大小适应页面,也可以换成下方的自定义大小设置 256 | %p1.Style={HAlign('center'),ScaleToFit(1)}; 257 | p1.Style={HAlign('center'),Width('600px'),Height('400px')}; 258 | append(d,p1); 259 | 260 | close(d); 261 | rptview(d.OutputPath); 262 | ``` 263 | 264 | 作为一个懒人,我希望写得更极致一点, 即我只想关注内容而忽略这些格式。这时候我们可以利用模板来实现这一切,把所需要的样式都存在模板里。事实上新建Word文档都是基于模板建立的,Matlab也是。通过在模板里修改默认样式或者新建样式,我们可以极大简化上述代码,从而使得上述工作不那么像编程。 265 | 266 | ### 1.7 巧用模板来简化代码 267 | 268 | ```Matlab 269 | % demo3.m 270 | % 利用模板中的样式来生成报告 271 | % 如果是中文版Word,自带样式名称请参见目录下的pdf文档 272 | 273 | import mlreportgen.dom.* 274 | % 模板文件 mytemplate.dotx 在文末会附下载链接 275 | d=Document('demo3','docx',fullfile(pwd,'mytemplate')); 276 | open(d); 277 | %% 标题 278 | p=Paragraph('成绩报告单','Heading 1'); 279 | append(d,p); 280 | %% 文字段落(doc mlreportgen.dom.Paragraph) 281 | append(d,Heading(2,'一、段落模板')); 282 | s='这里是段落'; 283 | s=repmat(s,[1,30]); 284 | p = Paragraph(s,'mypara1');%自定义段落样式 285 | append(d,p); 286 | %% 添加空的段落行 287 | for i=1:8 288 | append(d,' '); 289 | end 290 | %% 插入表格 291 | append(d,Heading(2,'二、表格模板')); 292 | t={'姓名','语文','数学','英语'; ... 293 | '成绩','70','94','82'; ... 294 | '等级','C','A','B'}; 295 | p=Table(t,'mytable1');% 自定义表格样式 296 | append(d,p); 297 | close(d); 298 | rptview(d.OutputPath); 299 | 300 | ``` 301 | 302 | 到这一个完整的模板就差不多了,还有一些新的类需要读者自己去探索。 接下来才是本文的正题,我们来玩一点好玩的事情。 303 | 304 | 305 | 306 | 307 | ## 2. 批量生成成绩单 308 | 309 | >数据集和目标: 310 | 1. 班级所有人的成绩表(成绩.xlsx):姓名、语文、数学、总分; 311 | 2. 给每个同学生一张成绩单,其中只有自己一个人的分数和相对应的等级。 312 | 313 | 314 | ```Matlab 315 | % SchoolReport.m 316 | % n=学生人数 317 | % 为使得程序可读性加强,我们需要格式化成绩单 318 | % 1. 第一行格式:姓名,各个学科,总分 319 | % 2. 只有学生成绩,没有其他很杂的信息。 320 | % 3. 部分成绩若空缺,请不要用数字填充,可以空着或者文字(缺考)填充。 321 | 322 | %% 数据导入 323 | filename='成绩.xlsx'; 324 | savename='成绩单'; 325 | [score,textdata]=xlsread(filename); 326 | m=3; %学科数 327 | n=size(score,1);% 学生人数 328 | name=textdata(2:n+1,1); 329 | mean_score=mean(score,'omitnan'); 330 | max_score=max(score,[],'omitnan'); 331 | grade=Gradegen(score); %Gradegen是自定义函数,生成各个同学的等级 332 | 333 | %模板,实考对应变量score,等级对应变量grade 334 | template=cell(5,m+1); 335 | template(1,1:m+1)={'姓名','语文','数学','总分'}; 336 | template(2:5,1)={'实考成绩';'平均成绩';'最高成绩';'等级'}; 337 | 338 | %% 相关接口 339 | import mlreportgen.dom.*; 340 | d = Document(savename,'docx',fullfile(pwd,'mytemplate')); 341 | open(d); 342 | 343 | %% 开始生成word成绩单列表 344 | 345 | % 添加分割线 346 | hr = HorizontalRule(); 347 | hr.Style={Border('dotdash','blue','2px')}; 348 | append(d,hr); 349 | % n是学生人数,m是学科数 350 | for i=1:n 351 | % 填充表格 352 | template{1,1}=name{i}; 353 | for jj=2:m+1 354 | s=score(i,jj-1); 355 | if isnan(s) 356 | s='缺考'; 357 | else 358 | s=num2str(s); 359 | end 360 | template{2,jj}=s;% 具体分数 361 | template{3,jj}=sprintf('%4.2f',mean_score(jj-1));%学科平均分数 362 | template{4,jj}=num2str(max_score(jj-1));%学科最高分数 363 | template{5,jj}=grade{i,jj-1};% 等级 364 | end 365 | 366 | q=Table(template,'mytable2'); 367 | q.TableEntriesStyle={Width('100'),Height('50')}; 368 | append(d,q); 369 | append(d,clone(hr)); 370 | end 371 | close(d); 372 | rptview(d.OutputPath); 373 | ``` 374 | 375 | 成果预览: 376 | 377 | ![schoolreport.png](schoolreport.png) 378 | 379 | 除此之外,本文还提供了一个批量生成奖状的模板(在Word里也可以通过邮件合并功能实现)供参考。 380 | 381 | 382 | ![jiangzhuang.png](jiangzhuang.png) 383 | 384 | 385 | 386 | 387 | -------------------------------------------------------------------------------- /report/SchoolReport.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/SchoolReport.m -------------------------------------------------------------------------------- /report/demo1.m: -------------------------------------------------------------------------------- 1 | % demo1.m 2 | import mlreportgen.dom.*; 3 | d = Document('demo1','docx'); 4 | open(d); 5 | append(d,'hello world!'); 6 | % p=Text('hello world'); 7 | % p.Style={Bold(true),FontSize('16pt'),Color('blue')}; 8 | % p.Strike='double'; 9 | close(d); 10 | rptview(d.OutputPath); -------------------------------------------------------------------------------- /report/demo2.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/demo2.m -------------------------------------------------------------------------------- /report/demo3.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/demo3.m -------------------------------------------------------------------------------- /report/jiangzhuang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/jiangzhuang.png -------------------------------------------------------------------------------- /report/myPlot_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/myPlot_img.png -------------------------------------------------------------------------------- /report/mytemplate.dotx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/mytemplate.dotx -------------------------------------------------------------------------------- /report/rptgen.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/rptgen.pdf -------------------------------------------------------------------------------- /report/schoolreport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/schoolreport.png -------------------------------------------------------------------------------- /report/成绩.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/成绩.xlsx -------------------------------------------------------------------------------- /report/成绩单.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/成绩单.docx -------------------------------------------------------------------------------- /report/批量生成奖状.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gasongjian/reportgen_matlab/7e4dbff432756e319575acac3baab3067d19e5e0/report/批量生成奖状.docx --------------------------------------------------------------------------------