1.先创建一个word文件(建议word2003,低版本兼容性好一点),在word中按照自己的需求做好文档。


2.另存为xml文件(建议与word一致即word2003xml),用可以查看xml文件的软件打开。如下图:


 

 




freemarker生成html文件 freemarker生成图片_freemarker生成html文件


这一大段黑色文字就是图片由word转成xml生成的Base64码。这样的格式太乱了,建议使用firstObject xml编辑器可以格式化。


如下图:



freemarker生成html文件 freemarker生成图片_freemarker生成html文件_02


将大段黑色文字替换为图片占位符${qrCodeList.imagedata}


 

 



freemarker生成html文件 freemarker生成图片_word_03


将会变化的字段改为占位符${qrCodeList.row},${qrCodeList.col}


 

 

<w:tbl></w:tbl>表示表格 

 

  <w:tr></w:tr>表示行 

 

  <w:tc></w:tc>表示列 

 

  <#list></#list>表示需要循环的列表--例如<#list qrCodeList as qrCode></#list> 

 

  qrCodeList是后台传过来的数据名称例如 

 

  dataMap("qrCodeList",list);


list中也可以是list


qrCode是数据元素

 


编辑好后保存,保存后直接修改文件为.ftl文件例如model.ftl


3.在pom.xml文件中引入freemarker


<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.23</version>
</dependency>


 

 

 


4.创建工具类ExportWord(若configuration报空异常,请在createWord方法中创建 (不建议这么做))


 


public class ExportWord {

    private static final String templateFolder = ExportWord.class.getClassLoader().getResource("../..").getPath()+"/ftl";
    private Configuration configuration = null;
   
    public ExportWord(){
        configuration = new Configuration();
        configuration.setDefaultEncoding("UTF-8");
    }
    public File createWord(Map<String, Object> dataMap, String hallName) throws Exception {
        Date date = new Date();
       
        configuration.setDirectoryForTemplateLoading(new File(templateFolder));
        configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
        Template t = null;
        try {
            t = configuration.getTemplate("model.ftl"); // 文件名
        } catch (IOException e) {
            e.printStackTrace();
        }
        File outFile = new File(hallName+date.getTime() + ".doc");
        Writer w = null;
        try {
            w = new OutputStreamWriter(new FileOutputStream(outFile), "utf-8");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        try {
            t.process(dataMap, w);
            w.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return outFile;
    }

    public void getData(Map<String, Object> dataMap,List<SeatInfo> seatInfo,MovieHallExt movieHallExt) {
        int sum = Integer.parseInt(movieHallExt.getHallCapacity());
        List<List<QRCode>> qrCodes = new ArrayList<>();
        List<QRCode> list = new ArrayList<>();
        for (int i = 0;i<sum ;i++){
               QRCode qrCode = new QRCode();
               qrCode.setImagedata(getImageStr(seatInfo.get(i).getRowId(),seatInfo.get(i).getColId()));
               qrCode.setRow(Integer.parseInt(seatInfo.get(i).getRowId()));
               qrCode.setCol(Integer.parseInt(seatInfo.get(i).getColId()));
               list.add(qrCode);
           }
        for(int c = 0;c < sum;c=c+6){
            if(c+6 < sum){
               qrCodes.add(list.subList(c,c+6));
            }else{
               qrCodes.add(list.subList(c,sum));
            }
        }
           dataMap.put("qrCodes",qrCodes);
    }

    private String getImageStr(String row,String col) {
        String content = row + "-" + col;
        BufferedImage image = null;
        ByteArrayOutputStream outputStream =null;
        try{
            image = QRCodeServiceImpl.createQRCode(content);
            outputStream = new ByteArrayOutputStream();
            ImageIO.write(image, "jpg", outputStream);
        }catch (Exception e){

        }
        String imageCodeBase64 = Base64.encodeBase64String(outputStream.toByteArray());
        return imageCodeBase64;
    }


}


5.controller调用ExportWord工具类


 

@RequestMapping("/exportReport")
    public void exportReport(String hallCode,HttpServletResponse response, HttpServletRequest request, String picBase64Info1) {
        Result result = new Result();
        List<SeatInfo> seatInfo = takeoutService.getSeatInfo(hallCode);
        MovieHallExt movieHallExt = takeoutService.getHallByCode(hallCode);
        ExportWord test = new ExportWord();
        Map<String, Object> dataMap = new HashMap<String, Object>();
        File file = null;
        try {
            test.getData(dataMap,seatInfo,movieHallExt);
            file  = test.createWord(dataMap,movieHallExt.getHallName());
            result.setResultCode("0");
        }catch (Exception e){
            result.setResultCode("1");
            System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"+e);
        }

        InputStream fin = null;
        OutputStream out = null;
        try{
            fin = new FileInputStream(file);

            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream; charset=utf-8");
//            response.setContentType("application/msword");
            response.setHeader("Content-Disposition","attachment; filename="+ Encodes.urlEncode(movieHallExt.getHallName())+".doc");
            out = response.getOutputStream();
            byte[] buffer = new byte[512];
            int b =-1;
            while ((b=fin.read(buffer))!= -1){
                out.write(buffer,0,b);
            }
            out.close();
            fin.close();
            result.setResultCode("0");
        }catch (Exception e){
            e.printStackTrace();
            System.out.println(e);
            result.setResultCode("1");
        }finally {
            try{
                if(out!=null){
                out.close();
                }
                if(fin != null){
                    fin.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        }
    }


 


 


 

 


6.难点解决


在网上有经典的三种读取模板的方法:


 

public void setClassForTemplateLoading(Class clazz, String pathPrefix);
public void setDirectoryForTemplateLoading(File dir) throws IOException;
public void setServletContextForTemplateLoading(Object servletContext, String path);

 

第一种:基于类路径,HttpWeb包下的framemaker.ftl文件(例如你的模板文件在包com.templete.ftl下)  configuration.setClassForTemplateLoading(this.getClass(), "/com/templete/ftl");(用这种方法一开始读成功一次,后面报null)。

 

configuration.getTemplate("framemaker.ftl"); //framemaker.ftl为要装载的模板

第二种:基于文件系统(例如模板D盘的ftl文件夹,操作正确不会报错)。

configuration.setDirectoryForTemplateLoading(new File("D:/ftl/");
configuration.getTemplate("framemaker.ftl"); //framemaker.ftl为要装载的模板

第三种:基于Servlet Context,指的是基于WebRoot下的template下的framemaker.ftl文件(不适合基于springboot的项目)

HttpServletRequest request = ServletActionContext.getRequest();
configuration.setServletContextForTemplateLoading(request.getSession().getServletContext(), "/template");
 
 
 

  configuration.getTemplate("framemaker.ftl"); //framemaker.ftl为要装载的模板


 

 


在这三种方式中只有第二种基于文件系统的,可用且稳定。但是这只能基于在本机运行。


最后找到下面这个方法也是基于第二种方法的但是将模板文件放在WEB-INF下的某个文件里的(自己建个就可以)


 

 


例如在WEB-INF中的ftl文件夹中可以这样读:


private static final String templateFolder = ExportWord.class.getClassLoader().getResource("../..").getPath()+"/ftl";

 

configuration.setDirectoryForTemplateLoading(new File(templateFolder));
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
Template t = null;
try {
    t = configuration.getTemplate("model.ftl"); // 文件名
} catch (IOException e) {
    e.printStackTrace();
}


这样项目就可以部署到其他地方了。


 

 

 


效果图



freemarker生成html文件 freemarker生成图片_freemarker_04


 


 

 


ftl文件


<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
 
 <?mso-application progid="Word.Document"?>  
 <w:wordDocument xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wsp="http://schemas.microsoft.com/office/word/2003/wordml/sp2" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve">  
 <w:ignoreSubtree w:val="http://schemas.microsoft.com/office/word/2003/wordml/sp2"/>  
 <o:DocumentProperties>  
 <o:Author>Windows 用户</o:Author>  
 <o:LastAuthor>Windows 用户</o:LastAuthor>  
 <o:Revision>1</o:Revision>  
 <o:TotalTime>8</o:TotalTime>  
 <o:Created>2018-05-18T04:22:00Z</o:Created>  
 <o:LastSaved>2018-05-18T04:30:00Z</o:LastSaved>  
 <o:Pages>1</o:Pages>  
 <o:Words>2</o:Words>  
 <o:Characters>14</o:Characters>  
 <o:Lines>1</o:Lines>  
 <o:Paragraphs>1</o:Paragraphs>  
 <o:CharactersWithSpaces>15</o:CharactersWithSpaces>  
 <o:Version>14</o:Version>  
 </o:DocumentProperties>  
 <w:fonts>  
 <w:defaultFonts w:ascii="Calibri" w:fareast="宋体" w:h-ansi="Calibri" w:cs="Times New Roman"/>  
 <w:font w:name="Times New Roman">  
 <w:panose-1 w:val="02020603050405020304"/>  
 <w:charset w:val="00"/>  
 <w:family w:val="Roman"/>  
 <w:pitch w:val="variable"/>  
 <w:sig w:usb-0="E0002EFF" w:usb-1="C000785B" w:usb-2="00000009" w:usb-3="00000000" w:csb-0="000001FF" w:csb-1="00000000"/>  
 </w:font>  
 <w:font w:name="宋体">  
 <w:altName w:val="SimSun"/>  
 <w:panose-1 w:val="02010600030101010101"/>  
 <w:charset w:val="86"/>  
 <w:family w:val="auto"/>  
 <w:pitch w:val="variable"/>  
 <w:sig w:usb-0="00000003" w:usb-1="288F0000" w:usb-2="00000016" w:usb-3="00000000" w:csb-0="00040001" w:csb-1="00000000"/>  
 </w:font>  
 <w:font w:name="Cambria Math">  
 <w:panose-1 w:val="02040503050406030204"/>  
 <w:charset w:val="01"/>  
 <w:family w:val="Roman"/>  
 <w:notTrueType/>  
 <w:pitch w:val="variable"/>  
 </w:font>  
 <w:font w:name="Calibri">  
 <w:panose-1 w:val="020F0502020204030204"/>  
 <w:charset w:val="00"/>  
 <w:family w:val="Swiss"/>  
 <w:pitch w:val="variable"/>  
 <w:sig w:usb-0="E0002AFF" w:usb-1="C000247B" w:usb-2="00000009" w:usb-3="00000000" w:csb-0="000001FF" w:csb-1="00000000"/>  
 </w:font>  
 <w:font w:name="@宋体">  
 <w:panose-1 w:val="02010600030101010101"/>  
 <w:charset w:val="86"/>  
 <w:family w:val="auto"/>  
 <w:pitch w:val="variable"/>  
 <w:sig w:usb-0="00000003" w:usb-1="288F0000" w:usb-2="00000016" w:usb-3="00000000" w:csb-0="00040001" w:csb-1="00000000"/>  
 </w:font>  
 </w:fonts>  
 <w:styles>  
 <w:versionOfBuiltInStylenames w:val="7"/>  
 <w:latentStyles w:defLockedState="off" w:latentStyleCount="267">  
 <w:lsdException w:name="Normal"/>  
 <w:lsdException w:name="heading 1"/>  
 <w:lsdException w:name="heading 2"/>  
 <w:lsdException w:name="heading 3"/>  
 <w:lsdException w:name="heading 4"/>  
 <w:lsdException w:name="heading 5"/>  
 <w:lsdException w:name="heading 6"/>  
 <w:lsdException w:name="heading 7"/>  
 <w:lsdException w:name="heading 8"/>  
 <w:lsdException w:name="heading 9"/>  
 <w:lsdException w:name="toc 1"/>  
 <w:lsdException w:name="toc 2"/>  
 <w:lsdException w:name="toc 3"/>  
 <w:lsdException w:name="toc 4"/>  
 <w:lsdException w:name="toc 5"/>  
 <w:lsdException w:name="toc 6"/>  
 <w:lsdException w:name="toc 7"/>  
 <w:lsdException w:name="toc 8"/>  
 <w:lsdException w:name="toc 9"/>  
 <w:lsdException w:name="caption"/>  
 <w:lsdException w:name="Title"/>  
 <w:lsdException w:name="Default Paragraph Font"/>  
 <w:lsdException w:name="Subtitle"/>  
 <w:lsdException w:name="Strong"/>  
 <w:lsdException w:name="Emphasis"/>  
 <w:lsdException w:name="Table Grid"/>  
 <w:lsdException w:name="Placeholder Text"/>  
 <w:lsdException w:name="No Spacing"/>  
 <w:lsdException w:name="Light Shading"/>  
 <w:lsdException w:name="Light List"/>  
 <w:lsdException w:name="Light Grid"/>  
 <w:lsdException w:name="Medium Shading 1"/>  
 <w:lsdException w:name="Medium Shading 2"/>  
 <w:lsdException w:name="Medium List 1"/>  
 <w:lsdException w:name="Medium List 2"/>  
 <w:lsdException w:name="Medium Grid 1"/>  
 <w:lsdException w:name="Medium Grid 2"/>  
 <w:lsdException w:name="Medium Grid 3"/>  
 <w:lsdException w:name="Dark List"/>  
 <w:lsdException w:name="Colorful Shading"/>  
 <w:lsdException w:name="Colorful List"/>  
 <w:lsdException w:name="Colorful Grid"/>  
 <w:lsdException w:name="Light Shading Accent 1"/>  
 <w:lsdException w:name="Light List Accent 1"/>  
 <w:lsdException w:name="Light Grid Accent 1"/>  
 <w:lsdException w:name="Medium Shading 1 Accent 1"/>  
 <w:lsdException w:name="Medium Shading 2 Accent 1"/>  
 <w:lsdException w:name="Medium List 1 Accent 1"/>  
 <w:lsdException w:name="Revision"/>  
 <w:lsdException w:name="List Paragraph"/>  
 <w:lsdException w:name="Quote"/>  
 <w:lsdException w:name="Intense Quote"/>  
 <w:lsdException w:name="Medium List 2 Accent 1"/>  
 <w:lsdException w:name="Medium Grid 1 Accent 1"/>  
 <w:lsdException w:name="Medium Grid 2 Accent 1"/>  
 <w:lsdException w:name="Medium Grid 3 Accent 1"/>  
 <w:lsdException w:name="Dark List Accent 1"/>  
 <w:lsdException w:name="Colorful Shading Accent 1"/>  
 <w:lsdException w:name="Colorful List Accent 1"/>  
 <w:lsdException w:name="Colorful Grid Accent 1"/>  
 <w:lsdException w:name="Light Shading Accent 2"/>  
 <w:lsdException w:name="Light List Accent 2"/>  
 <w:lsdException w:name="Light Grid Accent 2"/>  
 <w:lsdException w:name="Medium Shading 1 Accent 2"/>  
 <w:lsdException w:name="Medium Shading 2 Accent 2"/>  
 <w:lsdException w:name="Medium List 1 Accent 2"/>  
 <w:lsdException w:name="Medium List 2 Accent 2"/>  
 <w:lsdException w:name="Medium Grid 1 Accent 2"/>  
 <w:lsdException w:name="Medium Grid 2 Accent 2"/>  
 <w:lsdException w:name="Medium Grid 3 Accent 2"/>  
 <w:lsdException w:name="Dark List Accent 2"/>  
 <w:lsdException w:name="Colorful Shading Accent 2"/>  
 <w:lsdException w:name="Colorful List Accent 2"/>  
 <w:lsdException w:name="Colorful Grid Accent 2"/>  
 <w:lsdException w:name="Light Shading Accent 3"/>  
 <w:lsdException w:name="Light List Accent 3"/>  
 <w:lsdException w:name="Light Grid Accent 3"/>  
 <w:lsdException w:name="Medium Shading 1 Accent 3"/>  
 <w:lsdException w:name="Medium Shading 2 Accent 3"/>  
 <w:lsdException w:name="Medium List 1 Accent 3"/>  
 <w:lsdException w:name="Medium List 2 Accent 3"/>  
 <w:lsdException w:name="Medium Grid 1 Accent 3"/>  
 <w:lsdException w:name="Medium Grid 2 Accent 3"/>  
 <w:lsdException w:name="Medium Grid 3 Accent 3"/>  
 <w:lsdException w:name="Dark List Accent 3"/>  
 <w:lsdException w:name="Colorful Shading Accent 3"/>  
 <w:lsdException w:name="Colorful List Accent 3"/>  
 <w:lsdException w:name="Colorful Grid Accent 3"/>  
 <w:lsdException w:name="Light Shading Accent 4"/>  
 <w:lsdException w:name="Light List Accent 4"/>  
 <w:lsdException w:name="Light Grid Accent 4"/>  
 <w:lsdException w:name="Medium Shading 1 Accent 4"/>  
 <w:lsdException w:name="Medium Shading 2 Accent 4"/>  
 <w:lsdException w:name="Medium List 1 Accent 4"/>  
 <w:lsdException w:name="Medium List 2 Accent 4"/>  
 <w:lsdException w:name="Medium Grid 1 Accent 4"/>  
 <w:lsdException w:name="Medium Grid 2 Accent 4"/>  
 <w:lsdException w:name="Medium Grid 3 Accent 4"/>  
 <w:lsdException w:name="Dark List Accent 4"/>  
 <w:lsdException w:name="Colorful Shading Accent 4"/>  
 <w:lsdException w:name="Colorful List Accent 4"/>  
 <w:lsdException w:name="Colorful Grid Accent 4"/>  
 <w:lsdException w:name="Light Shading Accent 5"/>  
 <w:lsdException w:name="Light List Accent 5"/>  
 <w:lsdException w:name="Light Grid Accent 5"/>  
 <w:lsdException w:name="Medium Shading 1 Accent 5"/>  
 <w:lsdException w:name="Medium Shading 2 Accent 5"/>  
 <w:lsdException w:name="Medium List 1 Accent 5"/>  
 <w:lsdException w:name="Medium List 2 Accent 5"/>  
 <w:lsdException w:name="Medium Grid 1 Accent 5"/>  
 <w:lsdException w:name="Medium Grid 2 Accent 5"/>  
 <w:lsdException w:name="Medium Grid 3 Accent 5"/>  
 <w:lsdException w:name="Dark List Accent 5"/>  
 <w:lsdException w:name="Colorful Shading Accent 5"/>  
 <w:lsdException w:name="Colorful List Accent 5"/>  
 <w:lsdException w:name="Colorful Grid Accent 5"/>  
 <w:lsdException w:name="Light Shading Accent 6"/>  
 <w:lsdException w:name="Light List Accent 6"/>  
 <w:lsdException w:name="Light Grid Accent 6"/>  
 <w:lsdException w:name="Medium Shading 1 Accent 6"/>  
 <w:lsdException w:name="Medium Shading 2 Accent 6"/>  
 <w:lsdException w:name="Medium List 1 Accent 6"/>  
 <w:lsdException w:name="Medium List 2 Accent 6"/>  
 <w:lsdException w:name="Medium Grid 1 Accent 6"/>  
 <w:lsdException w:name="Medium Grid 2 Accent 6"/>  
 <w:lsdException w:name="Medium Grid 3 Accent 6"/>  
 <w:lsdException w:name="Dark List Accent 6"/>  
 <w:lsdException w:name="Colorful Shading Accent 6"/>  
 <w:lsdException w:name="Colorful List Accent 6"/>  
 <w:lsdException w:name="Colorful Grid Accent 6"/>  
 <w:lsdException w:name="Subtle Emphasis"/>  
 <w:lsdException w:name="Intense Emphasis"/>  
 <w:lsdException w:name="Subtle Reference"/>  
 <w:lsdException w:name="Intense Reference"/>  
 <w:lsdException w:name="Book Title"/>  
 <w:lsdException w:name="Bibliography"/>  
 <w:lsdException w:name="TOC Heading"/>  
 </w:latentStyles>  
 <w:style w:type="paragraph" w:default="on" w:styleId="a">  
 <w:name w:val="Normal"/>  
 <wx:uiName wx:val="正文"/>  
 <w:pPr>  
 <w:widowControl w:val="off"/>  
 <w:jc w:val="both"/>  
 </w:pPr>  
 <w:rPr>  
 <wx:font wx:val="Calibri"/>  
 <w:kern w:val="2"/>  
 <w:sz w:val="21"/>  
 <w:sz-cs w:val="22"/>  
 <w:lang w:val="EN-US" w:fareast="ZH-CN" w:bidi="AR-SA"/>  
 </w:rPr>  
 </w:style>  
 <w:style w:type="character" w:default="on" w:styleId="a0">  
 <w:name w:val="Default Paragraph Font"/>  
 <wx:uiName wx:val="默认段落字体"/>  
 </w:style>  
 <w:style w:type="table" w:default="on" w:styleId="a1">  
 <w:name w:val="Normal Table"/>  
 <wx:uiName wx:val="普通表格"/>  
 <w:rPr>  
 <wx:font wx:val="Calibri"/>  
 <w:lang w:val="EN-US" w:fareast="ZH-CN" w:bidi="AR-SA"/>  
 </w:rPr>  
 <w:tblPr>  
 <w:tblInd w:w="0" w:type="dxa"/>  
 <w:tblCellMar>  
 <w:top w:w="0" w:type="dxa"/>  
 <w:left w:w="108" w:type="dxa"/>  
 <w:bottom w:w="0" w:type="dxa"/>  
 <w:right w:w="108" w:type="dxa"/>  
 </w:tblCellMar>  
 </w:tblPr>  
 </w:style>  
 <w:style w:type="list" w:default="on" w:styleId="a2">  
 <w:name w:val="No List"/>  
 <wx:uiName wx:val="无列表"/>  
 </w:style>  
 <w:style w:type="table" w:styleId="a3">  
 <w:name w:val="Table Grid"/>  
 <wx:uiName wx:val="网格型"/>  
 <w:basedOn w:val="a1"/>  
 <w:rsid w:val="00F76479"/>  
 <w:rPr>  
 <wx:font wx:val="Calibri"/>  
 </w:rPr>  
 <w:tblPr>  
 <w:tblInd w:w="0" w:type="dxa"/>  
 <w:tblBorders>  
 <w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>  
 <w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>  
 <w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>  
 <w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>  
 <w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>  
 <w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/>  
 </w:tblBorders>  
 <w:tblCellMar>  
 <w:top w:w="0" w:type="dxa"/>  
 <w:left w:w="108" w:type="dxa"/>  
 <w:bottom w:w="0" w:type="dxa"/>  
 <w:right w:w="108" w:type="dxa"/>  
 </w:tblCellMar>  
 </w:tblPr>  
 </w:style>  
 <w:style w:type="paragraph" w:styleId="a4">  
 <w:name w:val="Balloon Text"/>  
 <wx:uiName wx:val="批注框文本"/>  
 <w:basedOn w:val="a"/>  
 <w:link w:val="Char"/>  
 <w:rsid w:val="00F76479"/>  
 <w:rPr>  
 <wx:font wx:val="Calibri"/>  
 <w:sz w:val="18"/>  
 <w:sz-cs w:val="18"/>  
 </w:rPr>  
 </w:style>  
 <w:style w:type="character" w:styleId="Char">  
 <w:name w:val="批注框文本 Char"/>  
 <w:link w:val="a4"/>  
 <w:rsid w:val="00F76479"/>  
 <w:rPr>  
 <w:sz w:val="18"/>  
 <w:sz-cs w:val="18"/>  
 </w:rPr>  
 </w:style>  
 </w:styles>  
 <w:shapeDefaults>  
 <o:shapedefaults v:ext="edit" spidmax="1026"/>  
 <o:shapelayout v:ext="edit">  
 <o:idmap v:ext="edit" data="1"/>  
 </o:shapelayout>  
 </w:shapeDefaults>  
 <w:docPr>  
 <w:view w:val="print"/>  
 <w:zoom w:percent="120"/>  
 <w:doNotEmbedSystemFonts/>  
 <w:bordersDontSurroundHeader/>  
 <w:bordersDontSurroundFooter/>  
 <w:defaultTabStop w:val="420"/>  
 <w:drawingGridHorizontalSpacing w:val="105"/>  
 <w:drawingGridVerticalSpacing w:val="156"/>  
 <w:displayHorizontalDrawingGridEvery w:val="0"/>  
 <w:displayVerticalDrawingGridEvery w:val="2"/>  
 <w:punctuationKerning/>  
 <w:characterSpacingControl w:val="CompressPunctuation"/>  
 <w:optimizeForBrowser/>  
 <w:allowPNG/>  
 <w:validateAgainstSchema/>  
 <w:saveInvalidXML w:val="off"/>  
 <w:ignoreMixedContent w:val="off"/>  
 <w:alwaysShowPlaceholderText w:val="off"/>  
 <w:compat>  
 <w:spaceForUL/>  
 <w:balanceSingleByteDoubleByteWidth/>  
 <w:doNotLeaveBackslashAlone/>  
 <w:ulTrailSpace/>  
 <w:doNotExpandShiftReturn/>  
 <w:adjustLineHeightInTable/>  
 <w:breakWrappedTables/>  
 <w:snapToGridInCell/>  
 <w:wrapTextWithPunct/>  
 <w:useAsianBreakRules/>  
 <w:dontGrowAutofit/>  
 <w:useFELayout/>  
 </w:compat>  
 <wsp:rsids>  
 <wsp:rsidRoot wsp:val="00F76479"/>  
 <wsp:rsid wsp:val="00F76479"/>  
 <wsp:rsid wsp:val="00FD1158"/>  
 </wsp:rsids>  
 </w:docPr>  
 <w:body>  
 <wx:sect>  
 <w:tbl>  
 <w:tblPr>  
 <w:tblW w:w="0" w:type="auto"/>  
 <w:tblLook w:val="04A0"/>  
 </w:tblPr>  
 <w:tblGrid>  
 <w:gridCol w:w="2376"/>  
 </w:tblGrid>  
外层循环开始<#list qrCodes as qrCodeList>  
 <w:tr wsp:rsidR="00F76479" wsp:rsidRPr="00F76479" wsp:rsidTr="00F76479">  
 <w:trPr>  
 <w:trHeight w:val="2117"/>  
 </w:trPr>  
内层循环<#list qrCodeList as qrCode>  
 <w:tc>  
 <w:tcPr>  
 <w:tcW w:w="2376" w:type="dxa"/>  
 <w:shd w:val="clear" w:color="auto" w:fill="auto"/>  
 </w:tcPr>  
 <w:p wsp:rsidR="00F76479" wsp:rsidRPr="00F76479" wsp:rsidRDefault="00F76479" wsp:rsidP="00F76479">  
 <w:pPr>  
 <w:jc w:val="center"/>  
 <w:rPr>  
 <w:rFonts w:hint="fareast"/>  
 </w:rPr>  
 </w:pPr>  
 <w:r wsp:rsidRPr="00F76479">  
 <w:rPr>  
 <wx:font wx:val="宋体"/>  
 </w:rPr>  
 <w:t>欢迎扫码点餐</w:t>  
 </w:r>  
 </w:p>  
 <w:p wsp:rsidR="00F76479" wsp:rsidRPr="00F76479" wsp:rsidRDefault="00F76479" wsp:rsidP="00F76479">  
 <w:pPr>  
 <w:jc w:val="center"/>  
 <w:rPr>  
 <w:rFonts w:hint="fareast"/>  
 </w:rPr>  
 </w:pPr>  
 <w:r wsp:rsidRPr="00FA2ACC">  
 <w:rPr>  
 <w:noProof/>  
 </w:rPr>  
 <w:pict>  
 <v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">  
 <v:stroke joinstyle="miter"/>  
 <v:formulas>  
 <v:f eqn="if lineDrawn pixelLineWidth 0"/>  
 <v:f eqn="sum @0 1 0"/>  
 <v:f eqn="sum 0 0 @1"/>  
 <v:f eqn="prod @2 1 2"/>  
 <v:f eqn="prod @3 21600 pixelWidth"/>  
 <v:f eqn="prod @3 21600 pixelHeight"/>  
 <v:f eqn="sum @0 0 1"/>  
 <v:f eqn="prod @6 1 2"/>  
 <v:f eqn="prod @7 21600 pixelWidth"/>  
 <v:f eqn="sum @8 21600 0"/>  
 <v:f eqn="prod @7 21600 pixelHeight"/>  
 <v:f eqn="sum @10 21600 0"/>  
 </v:formulas>  
 <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>  
 <o:lock v:ext="edit" aspectratio="t"/>  
 </v:shapetype>

记得修改name,要不图片重复第一张qrCode_index为循环下标

<w:binData w:name="${"wordml://qrcode_"+qrCodeList_index+qrCode_index+".jpg"}" xml:space="preserve">  
 ${qrCode.imagedata}  
 </w:binData>  
 <v:shape id="图片 1" o:spid="_x0000_i1025" type="#_x0000_t75" style="width:90.5pt;height:74.5pt;visibility:visible;mso-wrap-style:square">


记得修改src,要不图片重复第一张qrCode_index为循环下标


<v:imagedata src="${"wordml://qrcode_"+qrCodeList_index+qrCode_index+".jpg"}" o:title=""/> 
 
 </v:shape>  
 </w:pict>  
 </w:r>  
 </w:p>  
 <w:p wsp:rsidR="00F76479" wsp:rsidRPr="00F76479" wsp:rsidRDefault="00F76479" wsp:rsidP="00F76479">  
 <w:pPr>  
 <w:jc w:val="center"/>  
 </w:pPr>  
 <w:r wsp:rsidRPr="00F76479">  
 <w:rPr>  
 <w:rFonts w:hint="fareast"/>  
 </w:rPr>  
 <w:t>${qrCode.row}</w:t>  
 </w:r>  
 <w:r wsp:rsidRPr="00F76479">  
 <w:rPr>  
 <w:rFonts w:hint="fareast"/>  
 <wx:font wx:val="宋体"/>  
 </w:rPr>  
 <w:t>排</w:t>  
 </w:r>  
 <w:r wsp:rsidRPr="00F76479">  
 <w:rPr>  
 <w:rFonts w:hint="fareast"/>  
 </w:rPr>  
 <w:t>${qrCode.col}</w:t>  
 </w:r>  
 <w:r wsp:rsidRPr="00F76479">  
 <w:rPr>  
 <w:rFonts w:hint="fareast"/>  
 <wx:font wx:val="宋体"/>  
 </w:rPr>  
 <w:t>座</w:t>  
 </w:r>  
 </w:p>  
 </w:tc>  
内层循环结束</#list>  
 </w:tr>  
 <w:tr wsp:rsidR="005E20D3" wsp:rsidRPr="005E20D3" wsp:rsidTr="005E20D3">  
 <w:tc>  
 <w:tcPr>  
 <w:tcW w:w="2802" w:type="dxa"/>  
 <w:shd w:val="clear" w:color="auto" w:fill="auto"/>  
 </w:tcPr>  
 <w:p wsp:rsidR="005E20D3" wsp:rsidRPr="005E20D3" wsp:rsidRDefault="005E20D3" wsp:rsidP="00522DAD"/>  
 </w:tc>  
 </w:tr>  
外层循环结束</#list>  
 </w:tbl>  
 <w:p wsp:rsidR="00F76479" wsp:rsidRDefault="00F76479"/>  
 <w:sectPr wsp:rsidR="00F76479" wsp:rsidSect="00F76479">  
 <w:pgSz w:w="16838" w:h="11906" w:orient="landscape"/>  
 <w:pgMar w:top="1800" w:right="1440" w:bottom="1800" w:left="1440" 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>  
 </w:wordDocument>