java 导出word文档

java 导出word文档

1、设置模板

java 导出word文档_第1张图片

设置方法:

1、选中需要动态生成数据的部分,按 Ctrl+F9 -> 选择编辑域。
java 导出word文档_第2张图片

2.1、选择邮件合并,并在域代码部分后面加上相应参数,例如 :${videoNum} 'videoNum’是对应的参数名,后面代码编辑的时候会用到。
java 导出word文档_第3张图片

2.2、如果是表格类型的动态数据,按照2.1的方式设置参数,但参数以 ${video.name} 方式设置,用以后续动态数据的生成。
java 导出word文档_第4张图片

2、代码编写
2.1 pom导入
        
        <dependency>
            <groupId>org.apache.poigroupId>
            <artifactId>poiartifactId>
            <version>4.1.1version>
        dependency>
        <dependency>
            <groupId>org.apache.poigroupId>
            <artifactId>poi-ooxmlartifactId>
            <version>4.1.1version>
        dependency>
        <dependency>
            <groupId>org.jxlsgroupId>
            <artifactId>jxlsartifactId>
            <version>2.6.0version>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logbackgroupId>
                    <artifactId>logback-coreartifactId>
                exclusion>
            exclusions>
        dependency>
        <dependency>
            <groupId>org.jxlsgroupId>
            <artifactId>jxls-poiartifactId>
            <version>1.2.0version>
        dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreportgroupId>
            <artifactId>fr.opensagres.xdocreport.coreartifactId>
            <version>2.0.2version>
        dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreportgroupId>
            <artifactId>fr.opensagres.xdocreport.documentartifactId>
            <version>2.0.2version>
        dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreportgroupId>
            <artifactId>fr.opensagres.xdocreport.templateartifactId>
            <version>2.0.2version>
        dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreportgroupId>
            <artifactId>fr.opensagres.xdocreport.document.docxartifactId>
            <version>2.0.2version>
        dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreportgroupId>
            <artifactId>fr.opensagres.xdocreport.template.freemarkerartifactId>
            <version>2.0.2version>
        dependency>
        <dependency>
            <groupId>org.freemarkergroupId>
            <artifactId>freemarkerartifactId>
            <version>2.3.23version>
        dependency>
        <dependency>
            <groupId>commons-iogroupId>
            <artifactId>commons-ioartifactId>
            <version>2.5version>
        dependency>
2.2、代码编写
2.2.1、编写控制层
import com.fongtech.cli.report.service.ReportService;
import com.fongtech.cli.report.util.ResUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;


/**
 * @Author: lin
 * @Date: 2022/1/10 14:25
 * @Version 1.0
 */
@Slf4j
@RestController
@RequestMapping("/report")
@Api(tags = "报表相关接口")
public class ReportController {

    @Autowired
    private ReportService reportService;
    @GetMapping("/exportReportExcel")
    @ApiOperation("导出数据分析报告")
    public Object exportReportExcel(HttpServletRequest request,
                                    @RequestParam(value = "startDate", required = false) String startDate,
                                    @RequestParam(value = "endDate", required = false) String endDate,
                                    @RequestParam(value = "type", required = true) String type) {
        log.info("数据分析报告导出 开始时间:" + startDate + " 结束时间:" + endDate + " 类型:" + type);
        byte[] data = reportService.getWordByte(startDate, endDate, type);
        return ResUtil.getStreamData(request, data, "wordReportExport-" + type, "docx");
    }

}

2.2.2、编写service层
/**
 * @Author: linbo
 * @Date: 2022/1/10 14:25
 * @Version 1.0
 */
public interface ReportService {
    /**
     *  报告导出
     * @param startDate
     * @param endDate
     * @return
     */
    byte[] getWordByte(String startDate,String endDate, String type);
}
import com.fongtech.cli.report.util.ExportData;
import com.fongtech.cli.report.service.ReportService;
import com.fongtech.cli.report.util.SoMap;
import com.fongtech.cli.report.util.WordUtil;
import com.fongtech.cli.report.vo.ReportVo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author: lin
 * @Date: 2022/1/7 10:13
 * @Version 1.0
 */
@Service
public class ReportServiceImpl implements ReportService {
    /**
     * 模板文件的地址
     */
    @Value("${report.model-path-day}")
    private String MODEL_PATH_DAY;

    @Override
    public byte[] getWordByte(String startDate, String endDate, String type) {
        //准备数据
        ExportData evaluation = WordUtil.createExportData(MODEL_PATH_DAY);

        //时间设置
        String[] date = getDate(startDate);
        evaluation.setData("beginYear", date[0]);
        evaluation.setData("beginMonth", date[1]);
        evaluation.setData("beginDay", date[2]);
        String[] dateEnd = getDate(endDate);
        evaluation.setData("endYear", dateEnd[0]);
        evaluation.setData("endMonth", dateEnd[1]);
        evaluation.setData("endDay", dateEnd[2]);
        evaluation.setData("videoNum", "10");

        //设置视频监控状态
        List<SoMap> videoList = new ArrayList<SoMap>();
        for (int i = 0; i < 5; i++) {
            ReportVo reportVo = new ReportVo();
            reportVo.setName("园区名称" + i);
            reportVo.setPark("园区" + i);
            reportVo.setCondition("设备状态" + i);
            videoList.add(new SoMap(reportVo));
        }
        evaluation.setTable("video", videoList);
        // 获取新生成的文件流
        byte[] data = evaluation.getByteArr();
        return data;
    }

    private String[] getDate(String date) {
        if (date.contains(" ")) {

            return date.split("-| ");
        } else {
            return date.split("-");

        }
    }
}

application.yml文件:

report:
  model-path-day: "E://modelDay.docx"  #根据模板文件位置设定
2.2.3、Utile类设置

ExportData:

import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.images.ByteArrayImageProvider;
import fr.opensagres.xdocreport.document.images.IImageProvider;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import org.springframework.core.io.ClassPathResource;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class ExportData {

    private IXDocReport report;
    private IContext context;

    /**
     * 构造方法
     * @param report
     * @param context
     */
    public ExportData(IXDocReport report, IContext context) {
        this.report = report;
        this.context = context;
    }

    /**
     * 设置普通数据,包括基础数据类型,数组,试题对象
     * 使用时,直接 ${key.k} 或者 [#list d as key]
     * @param key   健
     * @param value 值
     */
    public void setData(String key, Object value) {
        context.put(key, value);
    }

    /**
     * 设置表格数据,用来循环生成表格的 List 数据
     * 使用时,直接 ${key.k}
     * @param key   健
     * @param maps List 集合
     */
    public void setTable(String key, List<SoMap> maps) {
        FieldsMetadata metadata = report.getFieldsMetadata();
        metadata = metadata == null ? new FieldsMetadata() : metadata;
        SoMap map = maps.get(0);
        for (String kk : map.keySet()) {
            metadata.addFieldAsList(key + "." + kk);
        }
        report.setFieldsMetadata(metadata);
        context.put(key, maps);
    }

    /**
     * 设置图片数据
     * 使用时 直接在书签出 key
     * @param key 健
     * @param url 图片地址
     */
    public void setImg(String key, String url) {
        FieldsMetadata metadata = report.getFieldsMetadata();
        metadata = metadata == null ? new FieldsMetadata() : metadata;
        metadata.addFieldAsImage(key);
        report.setFieldsMetadata(metadata);
        try (
                InputStream in = new ClassPathResource(url).getInputStream();
        ) {
            IImageProvider img = new ByteArrayImageProvider(in);
            context.put(key, img);
        } catch (IOException ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 获取文件流数据
     * @return 文件流数组
     */
    public byte[] getByteArr() {
        try (
                ByteArrayOutputStream out = new ByteArrayOutputStream();
        ) {
            report.process(context, out);
            return out.toByteArray();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex.getMessage());
        }
    }
}
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;

public class ResUtil {

    /**
     * 生成下载文件,浏览器直接访问为下载文件
     * @param request  请求对象
     * @param data     数据流数组
     * @param prefix   下载的文件名
     * @param suffix   文件后缀
     * @return 浏览器可以直接下载的文件流
     */
    public static ResponseEntity<byte[]> getStreamData(
            HttpServletRequest request, byte[] data, String prefix, String suffix
    ) {
        HttpHeaders headers = new HttpHeaders();
        prefix = StringUtils.isEmpty(prefix) ? "未命名" : prefix;
        suffix = suffix == null ? "" : suffix;
        try {
            String agent = request.getHeader("USER-AGENT");
            boolean isIE = null != agent, isMC = null != agent;
            isIE = isIE && (agent.indexOf("MSIE") != -1 || agent.indexOf("Trident") != -1);
            isMC = isMC && (agent.indexOf("Mozilla") != -1);
            prefix = isMC ? new String(prefix.getBytes("UTF-8"), "iso-8859-1") :
                    (isIE ? java.net.URLEncoder.encode(prefix, "UTF8") : prefix);
            headers.setContentDispositionFormData("attachment", prefix + "." + suffix);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            return new ResponseEntity<byte[]>(data, headers, HttpStatus.OK);
        } catch (UnsupportedEncodingException ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex.getMessage());
        }
    }
}
package com.fongtech.cli.report.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;

/**
 * @Author: linbo
 * @Date: 2022/1/4 11:38
 * @Version 1.0
 */
public class SoMap extends HashMap<String, Object> {


    public SoMap() { }

    /**
     * 构造方法,将任意实体类转化为 Map
     * @param obj
     */
    public SoMap(Object obj) {
        Class clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                this.put(field.getName(), field.get(obj));
            }
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 将 Map 转化为 任意实体类
     * @param clazz 反射获取类字节码对象
     * @return
     */
    public <T> T toEntity(Class<T> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        try {
            Constructor constructor = clazz.getDeclaredConstructor();
            T t = (T) constructor.newInstance();
            for (Field field : fields) {
                field.setAccessible(true);
                field.set(t, this.get(field));
            }
            return t;
        } catch (Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 从集合中获取一个字段的方法,如果字段不存在返回空
     * @param key  字段的唯一标识
     * @param   字段的类型,运行时自动识别,使用时无需声明和强转
     * @return     对应字段的值
     */
    public <T> T get(String key) {
        return (T) super.get(key);
    }

}
package com.fongtech.cli.report.util;

import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;

import java.io.FileInputStream;
import java.io.InputStream;

public class WordUtil {

    /**
     * 获取 Word 模板的两个操作对象 IXDocReport 和 IContext
     * @param path 模板绝对地址
     * @return 模板数据对象
     */
    public static ExportData createExportData(String path) {
        try {
            IXDocReport report = createReport(path);
            IContext context = report.createContext();
            return new ExportData(report, context);
        } catch (XDocReportException ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 加载模板的方法,主要是指定模板的路径和选择渲染数据的模板
     * @param url 模板相对于类路径的地址
     * @return word 文档操作类
     */
    private static IXDocReport createReport(String url) {
        try (
                InputStream in = new  FileInputStream(url);
        ) {
            IXDocReport ix = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
            return ix;
        } catch (Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

}

Vo类:

package com.fongtech.cli.report.vo;

import com.fongtech.cli.framework.model.BaseModel;

import java.io.Serializable;

/**
 * @Author: linbo
 * @Date: 2022/1/4 13:47
 * @Version 1.0
 */
public class ReportVo extends BaseModel implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private String transmissibility;
    private String condition;
    private String park;

    public String getPark() {
        return park;
    }

    public void setPark(String park) {
        this.park = park;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTransmissibility() {
        return transmissibility;
    }

    public void setTransmissibility(String transmissibility) {
        this.transmissibility = transmissibility;
    }

    public String getCondition() {
        return condition;
    }

    public void setCondition(String condition) {
        this.condition = condition;
    }
}

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fongtech.cli.cons.Constants;
import com.fongtech.cli.framework.model.convert.Convert;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

/**
 * 

* 自增主键父类 *

* */
@Data @NoArgsConstructor @EqualsAndHashCode(callSuper = false) public class BaseModel extends Convert { protected Integer id; @ApiModelProperty(notes = "删除标志") @TableLogic @TableField(fill = FieldFill.INSERT) private Integer deleteStatus; public boolean deleted() { return Constants.DELETED.equals(deleteStatus); } }

import com.fongtech.cli.framework.converter.BeanConverter;

import java.io.Serializable;

/**
 * 

* 普通实体父类 *

* */
public class Convert implements Serializable { /** * 获取自动转换后的JavaBean对象 * * @param clazz * @param * @return */ public <T> T convert(Class<T> clazz) { return BeanConverter.convert(clazz, this); } }
3、数据导出

java 导出word文档_第5张图片
java 导出word文档_第6张图片

你可能感兴趣的:(java,tool,java,后端)