精华内容
下载资源
问答
  • POI ,xdocreport框架是一个半成品,往往使用默认的解析结果无法满足业务需求,花了很长时间和心血研究了其源码,修复了以下问题 问题1: xdocreport能解析word转html,但解析出来的是基于word的整套html,往往我们的...
  • XDocReport XDocReport表示XML文档报告。 它是Java API,用于将使用MS Office(docx)或OpenOffice(odt),LibreOffice(odt)创建的XML文档与Java模型进行合并,以生成报告并将报告转换为其他格式(PDF,XHTML .....
  • xdocreport-2.0.1.jar

    2018-06-18 18:41:30
    xdocreport-2.0.1.jar,生成word文件等,只有jar,自行需要下载
  • 纯javadocx转pdf,windows下jacob转pdf,openoffice转pdf,docx文书替换,插入表格,图片等
  • XDocReport的简单使用

    万次阅读 2018-12-02 16:42:37
    XDocReport介绍初步了解XDocReport适用范围源码地址模板引擎一个填充的简单例子需求设计设计填充模板最终效果图填充字段设置我对填充字段的理解图片填充设置代码编写maven依赖填充类模板加载设置域模拟填充数据开始...

    初步了解XDocReport

    适用范围

    XDocReport是一个用来进行文档填充和文档格式转换的java api。在一些项目中,我们可能需要对一份模板里的某些字段进行填充,比如电子合同中需要填写双方信息以及一些金额数据。这时候,我们就可以用XDocReport来实现我们的功能。如果需要把word文档转成pdf,也可以用XDocReport,但是其对中文支持不太好,可能需要用其它工具。所以这篇文章也主要介绍如何使用XDocReport进行文档填充。

    文档填充支持的格式包括docx和odt,docx可以使用Office创建和查看,odt可以使用openoffice和libreoffice创建和查看。两种文档在设计模板上会有些许不同,在代码上没有任何区别,下面会详细介绍。

    源码地址

    在git上可以找到XDocReport的源码。在其README.md里有详细的Getting Started。通过官方教程,可以非常快速且详细地了解其使用方法。

    模板引擎

    XDocReport使用的模板引擎是freemarker和velocity,如果想具体什么是模板引擎以及上述两者模板引擎有什么区别,可以找些文章看看。需要提醒的是,官方教程大多数采用的是velocity(当然也有介绍freemarker),但是我这采用的freemarker。二者的填充占位符有所不同,这点需要注意,如果设置反了自然就不会填充成功了。

    一个填充的简单例子

    需求设计

    这里我们先模拟下需求:完成一份项目文档,需要填充的内容包括项目文档的标题、项目信息、相关人员信息以及一个logo。这里涉及的填充包括字符串填充,pojo填充,list填充以及图片填充,基本可以满足99%的实际需求。接下去,我们需要设计模板,然后再根据模板设计代码,最后进行测试。

    设计填充模板

    最终效果图

    我先展示模板的最终图(freemarker的占位符):

    填充字段设置

    首先是字段占位符的设置。我们的文档是docx格式,用office打开后,在你需要填充的地方,先按ctrl+f9,是不是出现了一对有阴影的括弧?如果没出现,可能是因为开启了笔记本上F1-F12的快捷键。在括弧上右键,选择“编辑域”,然后选择“MergeField”(如果是中文的就找找看意思相近的,貌似是邮件合并)。接着在上面填写占位符,如果到时候在程序上选择freemarker模板引擎,那么占位符就是 . . . , 占 位 符 里 填 写 占 位 的 字 符 串 。 如 果 是 v e l o c i t y 模 板 引 擎 , 那 么 占 位 符 就 是 {...},占位符里填写占位的字符串。如果是velocity模板引擎,那么占位符就是 ...,velocity,,然后后面填写占位的字符串。由于我打算用freemarker,所以可以从图片里看到,我的都是${…}。总结一下就是,ctrl+f9 -> 邮件编辑域 -> MergeField -> 填写占位符。

    如果填充的文档是odt格式,那么只需要填写占位符就好了。

    我对填充字段的理解

    上面也说过,填充的数据会包括字符串、pojo、list,所以他们占位符里的字段其实是不太一样的。其实,可以理解成java传到模板里的数据就是一个对象,如果对象是string,那么填充的就是其本身,如title;如果对象里包括多个成员变量,那么填充的就是对象里的成员变量,如project. name 和 project. info;如果对象是个list,那么其实在模板里是一样的,但是在java程序里会有所不同。

    图片填充设置

    说完了字段的填充,最后再说下图片的填充。图片的话,先随便插入一张图片,然后点下图片,对图片插入书签,设置书签名。OK,这样模板就搞定了。

    代码编写

    maven依赖

    	<dependencies>
            <!--xdocreport必备的依赖-->
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.document</artifactId>
                <version>2.0.1</version>
            </dependency>
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.core</artifactId>
                <version>2.0.1</version>
            </dependency>
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.template</artifactId>
                <version>2.0.1</version>
            </dependency>
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.converter</artifactId>
                <version>2.0.1</version>
            </dependency>
            <!--模板引擎相关-->
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
                <version>2.0.1</version>
            </dependency>
            <!--文档格式相关-->
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
                <version>2.0.1</version>
            </dependency>
        </dependencies>
    

    如果采用velocity引擎,或者文档格式为odt,那么就需要换成相应的依赖。

    填充类

    Project类

    	public class Project {
    	    private String name;
    	    private String info;
    	
    	    省略set、get和全参构造器
    	}
    

    Employee类

    	public class Employee {
    	    private String name;
    	    private String job;
    	    private String result;
    	
    	    //省略set、get和全参构造器
    	}
    

    模板加载

    		//1.通过freemarker模板引擎加载文档,并缓存到registry中
            InputStream in = new FileInputStream(
    							"E:\\project\\xdocreport\\file\\test.docx");
            IXDocReport report = XDocReportRegistry
                    .getRegistry()
                    .loadReport(in, TemplateEngineKind.Freemarker);
    

    这里指定了模板路径以及模板引擎。

    设置域

    		//2.设置填充字段、填充类以及是否为list。
            FieldsMetadata fieldsMetadata = report.createFieldsMetadata();
            fieldsMetadata.load("project", Project.class);
            fieldsMetadata.load("employees", Employee.class, true);
            fieldsMetadata.addFieldAsImage("logo");
            report.setFieldsMetadata(fieldsMetadata);
    

    结合之前写的模板里的填充字段,也就是域,可以发现

    1. title只是一个字符串,并不需要设置;
    2. project和employees的区别在于project是单个对象,而employees是多个对象的集合。所以这里employees要加个"true",表明它是个List。
    3. 图片设置和字段设置有所区别
    4. 这里设置的域的名字要和模板里的名字保持一致

    模拟填充数据

    		//3.模拟填充数据
    		String title = "项目开发报告";
            Project project = new Project("网站开发", "截至2018年年底");
            List<Employee> employees = new ArrayList<Employee>();
            employees.add(new Employee("张三", "产品", "任务完成"));
            employees.add(new Employee("李四", "开发", "任务完成"));
            IImageProvider logo = new FileImageProvider(
                                    new File("E:\\project\\xdocreport\\file\\1.jpg"),
                                            true);
            logo.setSize(200f, 100f);
    

    开始填充

    		//4.匹配填充字段和填充数据,进行填充
            IContext context = report.createContext();
            context.put("title", title);
            context.put("project", project);
            context.put("employees", employees);
            context.put("logo", logo);
            OutputStream out = new FileOutputStream(
                                new File("E:\\project\\xdocreport\\file\\test-out.docx"));
            report.process(context, out);
    

    测试结果

    更多内容…

    Getting Started的内容非常详细,还有能多内容没来得及看。

    第一次更新:2018.12.2

    展开全文
  • 简单介绍 在项目中经常会遇到报表相关的需求,而大多数会以excel出现,今天咱们说说word导出的一些事 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助...2.xdocreport开源工具 freemarker+ftl 引




    简单介绍

    在项目中经常会遇到报表相关的需求,而大多数会以excel出现,今天咱们说说word导出的一些事


    文章目录

    前言

    Java对word导出支持不太友好,由于本人水平有限,知道两种方式生成word文件。

    1.freemarker+ftl

    2.xdocreport开源工具


    freemarker+ftl

    引入freemarker包,准备好需要生成word模板的ftl文件。该文件是有word生成xml,在由xml修改后缀名得到的temp.ftl文件

     <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>

    缺点:word —>xml —>ftl 的过程繁琐且容易出错,ftl为标签内容不易读,如果模板变更又要重复word —>xml —>ftl 的过程。需要强大的内心和耐心。

    xdocreport开源工具

    该开源工具填写word模板语法一致,但不需要生成ftl文件作为模板,本身word就可直接作为导出模板。

    <dependency>
         <groupId>fr.opensagres.xdocreport</groupId>
         <artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
         <version>2.0.2</version>
    </dependency>
    <dependency>
         <groupId>fr.opensagres.xdocreport</groupId>
         <artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
         <version>2.0.2</version>
    </dependency>

    优点:可读性提高,修改模板是可以增量操作,无需复杂操作再次生成ftl文件


    一、freemarker导出word步骤

    • 新建word文档,写入内容样式,然后将动态获取的值放置内容展示区域
    • 将文件保存后,另存为xml格式
    • 打开文档显示内容如下,修改xml文件后缀名为ftl文件即可。
    • private void exportDoc(String fileName, HttpServletResponse response, String tempName) {
          PrintWriter writer = null;
      	Map<String, Object> dataMap = new HashMap<>();
          // 将要写入模板的数据塞到dataMap中。
      	dataMap.put("name":"i am kobe");
          try {
              Configuration configuration = new Configuration(new Version("2.3.0"));
              configuration.setDefaultEncoding("utf-8");
              // 上面配置模板的路径
              configuration.setClassForTemplateLoading(DocServiceImpl.class, "/templates");
              configuration.setTemplateLoader(new ClassTemplateLoader(DocServiceImpl.class, "/templates"));
              response.setContentType("application/msword");
              response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(fileName.getBytes("GBK"), "ISO-8859-1") + "\"");
              response.setCharacterEncoding("utf-8");
              writer = response.getWriter();
              // tempName是模板的文件名称
              Template template = configuration.getTemplate(tempName, "utf-8");
              template.process(dataMap, writer);
          } catch (Exception e) {
              logger.error("导出word文档异常 : {}", e);
          } finally {
              writer.flush();
              writer.close();
          }
      }

      这样就完成了freemarker配置以及下载word文档的功能了。


    二、xdocreport导出word步骤

    • 还是之前那个文档,同样的属性 name字段,之前是${name} 现在变成 word加域的形式
    • 如何加域,请看图片
    • 点击上方缺点即可。模板已经配置完成了,是不是方便了许多呢?
    • 上Java代码,直接撸代码了。
    • public void download(HttpServletRequest request,HttpServletResponse response){
      	try{
      		InputStream inputStream = new FileInputStream(new File("D:\\template.docx"));
      		IXDocReport report = XDocReportRegistry.getRegistry().loadReport(inputStream, TemplateEngineKind.Freemarker);
      		IContext context = report.createContext();
      		report.setFieldsMetadata(fieldsMetadata);
      		//替换word模板中创建的域的变量
      		context.put("name", "我叫张三");
      		//导出word
      		ByteArrayOutputStream bout = new ByteArrayOutputStream();
      		// 获取OutputStream 也就是写入bout
      		report.process(context, bout);
      		//创建文件输出流
      		FileOutputStream out = new FileOutputStream("d:\\daochudeword.docx");
      		out.write(bout.toByteArray());
      		out.close();
      		bout.close();
      	} catch (Exception e) {
      		e.printStackTrace();
      	}
      }


    三、常见语法介绍

    使用才是开始,语法才是修行。xdocreport的语法是兼容freemarker的。

    if判断的使用,下面是判断list集合是否为空且长度是否大于0

    [#if list?? && (list?size>0)]
    
    [#else]
        list 集合为空
    [/#if]
    
    
    [#if list?? && (list?size>0)]
    
    [/#if]

    对象判空

    [#if obj??]
    
    [/#if]

    数组的使用,循环输出多条数据

    [#list list as temp]
        ${temp}
    [/#list]

    总结

    很多语法不是很常用,if和list是本人在项目中运用的较多的,后续会及时更新相关语法。

    展开全文
  • 在完成这个功能时花费了大量的时间查阅资料,发现能满足导出复杂word文档的工具只有xdocreport,如果有其他的工具欢迎分享。废话不多说,上菜! 一、导入包 <dependency> <groupId>fr.opensagres....

    如果你要先问我为什么要导出word?那么请你走开,你个杠精!

    在完成这个功能时花费了大量的时间查阅资料,发现能满足导出复杂word文档的工具只有xdocreport,如果有其他的工具欢迎分享。废话不多说,上菜!

    一、导入包

     

    <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.core</artifactId>
                <version>2.0.2</version>
            </dependency>
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.document</artifactId>
                <version>2.0.2</version>
            </dependency>
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.template</artifactId>
                <version>2.0.2</version>
            </dependency>
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
                <version>2.0.2</version>
            </dependency>
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
                <version>2.0.2</version>
            </dependency>
            <dependency>
                <groupId>org.freemarker</groupId>
                <artifactId>freemarker</artifactId>
                <version>2.3.23</version>
            </dependency>
    相关包的具体版本没做详细研究,没那个时间。
    

    二、网络获取的基本的标签的一般用法

    1、${....}

    用于变量展示,也可以用作对象属性或者map值的展示,用法如下:

    对象属性:${object.XXX}

    map:${object["XXX"]}

    2、list

    数组、列表的循环展示,一般写法

    [#list list as item]

    ${item.a}

    [/#list]

    ps:很多教程说[#list list as item]要加引号,我发现没啥用,反而会让你展示的东西外面套一个引号!

    3、if

    一般写法

    [#if xxx]

    [#else][#elseif xxx]

    [/#if]

    eg:判断非null [#if (item.a)??][/#if]

    具体判断语法可以去自行了解。

    以上三个标签已经能够满足我目前的业务需求,其他的语法或者内置函数可以去如下宝藏地址了解,非常详细的总结。

    Xdocreport和Freemaker生成docx - 简书

     三、代码部分

     

    public void export(Long id) {
            OutputStream out = null;
            try {
                //获取Word模板,模板存放路径在项目的resources目录下
                InputStream ins = this.getClass().getResourceAsStream("/template.docx");
                //注册xdocreport实例并加载FreeMarker模板引擎
                IXDocReport report = XDocReportRegistry.getRegistry().loadReport(ins,
                        TemplateEngineKind.Freemarker);
                //创建xdocreport上下文对象
                IContext context = report.createContext();
                //获取需要导出的数据
                //对象数据
                Test1 test= xxx;
                //列表1
                List<Test2> cars = xxx;
                //列表2
                List<Test3> meals= xxx;
              
                
                context.put("test1", test.getA());
                context.put("cars",cars);
                context.put("meals",meals);
                HttpServletResponse response = ServletUtils.getResponse();
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/msword");
                response.setHeader("Content-Disposition", "attachment; filename=".concat(String.valueOf(URLEncoder.encode("i_am_name.docx", "UTF-8"))));
                out = response.getOutputStream();
                report.process(context, out);
                out.flush();
            } catch (IOException | XDocReportException e) {
                e.printStackTrace();
            }finally {
                try {
                    assert out != null;
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    简单文本代码就是这样,比较简单和基础,比较好消化,如果要搞一些导出图片什么的骚操作,请自行百度其他文章。

    那么好了,上肉菜!

    四、复杂模板编写

    题外前提:

            在word文档中,ctrl+F9会出现一对花括号,右键点击选择“编辑域”,类别选择“邮件合并”,域名选择“MergeFeild”,然后右侧域属性就可以编辑模板代码了。

            以上的一些内容足够支撑一个简单的word文档的导出业务,类似文本中局部文字的替换或者写入,简单规则表格的生成等。但是出现复杂表格的话会发现难以支撑,在我自己踩了N个坑之后做如下用法的总结;

    关于表格的导出,可以使用如下的标签来进行操作:

    @before-row[#list cars as car]}

    ${car.a}  ${car.b}

    @after-row[/#list]

    eg:

    «@before-row[#list cars as car]»«@after-row[/#list]»«${car.driverName}»«${car.driverNumber}»«${car.carNumber}»

    如果需要获取序号使用如下代码:${car?index+1}

    进阶版1:

    «@before-row[#list cars as car]»${car?index+1}«${car.carNumber}»«${car.driverANumber}»«${car.driverAName}»
    «${car.driverBNumber}»«${car.driverBName}»«@after-row[/#list]»

    进阶版2:

    需要进行非空判断时

    «@before-row[#list cars as car]»${car?index+1}

    «[#if (car.carNumber)??]

    ${car.carNumber}

    [/#if]»

    «${car.driverANumber}»«${car.driverAName}»
    «${car.driverBNumber}»«${car.driverBName}»«@after-row[/#list]»

    进阶版3:

    需要对列表项循环项进行非空判断时

    «@before-row

    [#if (cars)??]

    [#list cars as car]»${car?index+1}

    «[#if (car.carNumber)??]

    ${car.carNumber}

    [/#if]»

    «${car.driverANumber}»«${car.driverAName}»
    «${car.driverBNumber}»«${car.driverBName}»«@after-row[/#list][/#if]»

    注意此处[#if][/#if]的添加位置。进阶版3可满足任意的复杂表格的嵌套的模板的书写。

    时间有限,饭菜简单,吃完撤盘擦桌子,发现问题请多多指教。

    展开全文
  • 文档地址:...本文采用XDocReport集合Freemaiker进行处理 1. 引入Maven依赖: <dependency> <groupId>fr.opensagres.xdocreport</gr...

    文档地址:https://github.com/opensagres/xdocreport/wiki/DocxReportingQuickStart

    本文采用XDocReport集合Freemaiker进行处理

    1. 引入Maven依赖:

    <dependency>
        <groupId>fr.opensagres.xdocreport</groupId>
        <artifactId>xdocreport</artifactId>
        <version>2.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.23</version>
    </dependency>

    2. 创建Word模版

    新建Word,在光标处通过快捷键Ctrl+F9 或 工具栏“插入”->“文档部件或文本”->“域”

    根据电脑系统不同出现的界面不同,但内容都差不多,${text} 这个text就是后期要替换的变量了。

    3. Java代码处理逻辑

     1 String templateFilePath = request.getSession().getServletContext().getRealPath("/WEB-INF/templates/freemarkerTest.docx");
     2 File file = new File(templateFilePath);
     3 InputStream in = new FileInputStream(file);
     4 IXDocReport report;
     5 String targetPath = basePath + lawDownDto.getLawsName() + ".docx";
     6 try {
     7     report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
     8     // 设置内容为HTML格式
     9     FieldsMetadata metadata = report.createFieldsMetadata();
    10     metadata.addFieldAsTextStyling("text", SyntaxKind.Html);   
    11 
    12     // 创建内容-text为模版中对应都变量名称
    13     IContext context = report.createContext();
    14     context.put("text", content);
    15             
    16     // 生成文件
    17     OutputStream out = new FileOutputStream(targetPath);
    18     report.process(context, out);
    19 } catch (XDocReportException e) {
    20     e.printStackTrace();
    21 }

    文件下载:在生成文件逻辑后创建读取流返回即可。

    =============================================================

    如果文件中有图片需要处理:

      图片方案一:单个图片且位置固定,可通过XDocReport配置模版处理

      图片方案二:多个图片且位置不固定,可通过POI结合Freemarker进行处理

    图片方案一:

      1. 在模版中插入临时图片,选中图片并添加“书签”,书签名称是后续作为替换的变量

      

      2. 代码中追加逻辑

      在上面代码10后追加

    // logo为模版中标签名称
    metadata.addFieldAsImage("logo");
    report.setFieldsMetadata(metadata);

      在上面代码14行后追加

    // IImageProvider可通过3种方式创建(File/IO流/ClassPath下文件)具体可参考顶部文档-Dynamic Image
    IImageProvider logo = new FileImageProvider(new File("1950737_195902644.png"));
    context.put("logo", logo);

    图片方案二:

      1. 在上面读取模版之前进行数据替换

    // 处理文本中的图片,使用imgReplace变量替换
    Map<String, Object> param = new HashMap<String, Object>();
    if (StringUtils.isNotBlank(content)) {
        content = HtmlUtils.htmlUnescape(content);
        List<HashMap<String, String>> imgs = getImgStrContent(content);
        int count = 0;
        for (HashMap<String, String> img : imgs) {
            count++;
            //处理替换以“/>”结尾的img标签
            content = content.replace(img.get("img"), "${imgReplace" + count + "}");
            //处理替换以“>”结尾的img标签
            content = content.replace(img.get("img1"), "${imgReplace" + count + "}");
            Map<String, Object> header = new HashMap<String, Object>();
            String result = "";
            result = img.get("src");
            //如果没有宽高属性,默认设置为
            if(img.get("width") == null || img.get("height") == null) {
                header.put("width", 150);
                header.put("height", 150);
            }else {
                header.put("width", (int)(Double.parseDouble(img.get("width"))));
                header.put("height", (int) (Double.parseDouble(img.get("height"))));
            }
            if( StringUtils.isNotBlank(result) ){
                String type1 = result.substring(result.lastIndexOf(".") , result.length());
                header.put("type", type1);
                header.put("content",this.imageToInputStream(result));
            }
            param.put("${imgReplace" + count + "}", header);
        }
    }        
    //获取html中的图片元素信息
    private  List<HashMap<String, String>> getImgStrContent(String htmlStr) {
        List<HashMap<String, String>> pics = new ArrayList<HashMap<String, String>>();
        Document doc = Jsoup.parse(htmlStr);
        if( doc != null ){
            Elements imgs = doc.select("img");
            if( imgs != null && imgs.size() > 0 ){
                for (Element img : imgs) {
                    HashMap<String, String> map = new HashMap<String, String>();
                    if(!"".equals(img.attr("width"))) {
                        map.put("width", img.attr("width"));
                    }
                    if(!"".equals(img.attr("height"))) {
                        map.put("height", img.attr("height"));
                    }
                    map.put("img", img.toString().substring(0, img.toString().length() - 1) + "/>");
                    map.put("img1", img.toString());
                    map.put("src", img.attr("src"));
                    pics.add(map);
                }
            }
        }
        return pics;
    }
    // 读取生成的文件
    readStream = new FileInputStream(targetPath);
    ByteArrayOutputStream docxOs = new ByteArrayOutputStream();
    int b = 0;
    byte[] buf = new byte[1024];
    while ((b = readStream.read(buf)) != -1) {
        docxOs.write(buf, 0, b);
    }
    docxResponseStream = new ByteArrayInputStream(docxOs.toByteArray());
    // 创建word 对象
    XWPFDocument document = new XWPFDocument(docxResponseStream);
    newOS = new ByteArrayOutputStream();
    if (document != null && param != null) {
        // 生成带图片的word(如需工具类请给我发邮件)
        XWPFDocument customXWPFDocument = WordUtil.getWord(param, document);
        // 设置表格边框样式(另外一片文章会介绍)
        // List<XWPFTable> list = formatTableBorder(customXWPFDocument);
        // 处理合并单元格(另外一片文章会介绍)
        // mergeCell(content, list);
        // 写入输出流返回
        customXWPFDocument.write(newOS);
        document.close();
        customXWPFDocument.close();
        resultInpu = new ByteArrayInputStream(newOS.toByteArray());
    }else{
        resultInpu = docxResponseStream;
    }

    以上内容即可完成Word中多图片的动态展示。

    后续会写处理表格边框、单元格合并及段落都相关内容。

    转载于:https://www.cnblogs.com/commissar-Xia/p/11035471.html

    展开全文
  • 注意:docx内容字体需要是宋体,我用的office是2013版本的,我在2007版本上也测试过,是可以生成的,其他会乱码,不过xdocreport支持扩展字体 github的issue(需翻**墙) 总结**: 通过freemarkder+xdocreport生成pdf...
  • Xdocreport和Freemaker生成docx

    千次阅读 2017-06-21 14:31:00
    FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用...通过Xdocreport和Freemaker可用来生成docx文件GitHub:http://code.google.com/...
  • 依赖的jar包 <dependency>...fr.opensagres.xdocreport</groupId> <artifactId>xdocreport</artifactId> <version>2.0.2</version> </dependenc...
  • 一、xdocReport支持的报告模板有三种:Docx格式,PPTX格式,ODT格式。 二、重点讲如何用FreeMaker语法设计docx的文档报告模板): 虽然可以采用word宏来定义变量设计文档报告模板,但我个人不建议,因为无法做一些...
  • 一、我们在确定用xdocReport时要确定我们的需求,以下是我的需求: 1.采用docx作为文档模板,在里面定义freeMaker标签变量,最终和java模型结合生成docx文档。 2.采用freeMarker模板引擎(由于它的功能比...
  • (一)xdocreport能做什么? 1.xdocreport是一个java api,它能够根据ms office(docx或者ppt)以及open office的odt创建的xml文档模板,与java模型一起配合生成你想要的docx或者odt文档报告。 2.同时你可以把生成...
  • 首先创建一个maven工程 ... fr.opensagres.xdocreport fr.opensagres.xdocreport.converter.docx.xwpf 1.0.6 fr.opensagres.xdocreport org.apache.poi.xwpf.converter.pdf 1.0.6
  • 关键字:java xdocreport centos7 PDF 中文 不显示 在我的项目中出现了问题 生产(Linux)上就是word转pdf没有汉字显示,只有字母和数字。 因为liunx系统上,没有安装有中文字体库; 解决方案: 问题确认命令: 1、...
  • 【Exception】解决XDocReport生成word文件报错:numbering.xml错误   一、问题描述 1、使用 XDocReport根本模板生成word文件时,个别模板生成的word文档无法打开,报错信息: numbering.xml 错误 xx 行 。   ...
  • 最近项目需要pdf打印,通过调研和网上搜索xdocreport,处理图片和word,pdf无论是生成速度和内存消耗,比doc4j都要速度快,内存消耗小。开发一直在window下面,生成pdf正常,中文不会乱码,部署到linux服务器就各种...
  • 1.模板变量和后台对应word文档中插入文档部件 MergeField 变量名为${test}后台需要给 report 对象 一个同名的文本对象 context.put("test", availReportModelData.getException()); ...
  • XDocReport 主要是操作word,如动态插入数字、汉字、图片,也可以通过指令形式去执行程序输出结果。1,模版变量定义。 1)新建word; 2)替换简单动态变量:Ctrl + F9 编辑域 选择MergeField 编辑域代码 如图: ...
  • XDocReport 示例
  • XDocReport XDocReport means XML Document reporting. It's Java API to merge XML document created with MS Office (docx) or OpenOffice (odt), LibreOffice (odt) with a Java model to generate report and ...
  • MongoDB IDE 是用于管理数据库的 Eclipse 插件。 这些插件在几个上下文中工作: Eclipse集成开发环境 Eclipse RCP(胖客户端) Eclipse RAP (WEB)。 你可以在看到在线演示 有关更多信息,请阅读 [MongoDB IDE ...
  • XDocReport 主要是操作word,如动态插入数字、汉字、图片,也可以通过指令形式去执行程序输出结果。 1,模版变量定义。 1)新建word; 2)替换简单动态变量:Ctrl + F9 编辑域 选择MergeField 编辑域代码 如...
  • 后来查了xdocreport的源代码, 发下有以下字符: [link]...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 554
精华内容 221
关键字:

XDocReport