Javaweb中使用POI对Excel,word进行批量导入导出处理

JAVAWEB 同时被 2 个专栏收录
5 篇文章 0 订阅
4 篇文章 0 订阅

首先对EXCEL或者Word处理我们要懂得使用原则:
之前使用过NPOI常见基本都是在.net或者C#中使用,感兴趣可以去了解一下,大致相同;

首先是导入操作:

1.我们要进行文件上传(需要使用jar包fileupload),那么我们需要对文件流进行一个保存,最后面我们只需要拿到一个特定的地址即可,所以我们文件上传过程中需要拿到的是,文件名称,文件流,如果设置其他标题内容也是可以拿到的;
2.保存好文件那么就需要对文件进行解析,所以需要包(POI),然后进行存储,存储过程中我们要对前端进行数据的显示,那么如果连接数据库可以存数据库,否则则进行存本地操作,那么就需要对文件上传内容的要求定义类进行内容的存储,存储在MAP,LIST中之后进行调用;
3.前端调用使用的是EL和JSTL进行前端的调用,用于简化前端的代码,变得规范性;

综上所诉,所有需要导入的jar包:
在这里插入图片描述
接下来就是进行处理:

文件上传处理:

上传文件前端表单必须是这个:
在这里插入图片描述

package com.java.util;

import com.java.dto.ParamDto;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.List;

/**
 * 做一个解析帮助类,用来对上传下载内容的解析操作
 */
public class RequestHelper {
    /**
     * 数据流解析对上传内容进行解析操作;
     * @param request
     */
    private static final String SAVE_PATH = "K:/JavawebExportDown/web/import/";
    public static ParamDto parseParam(HttpServletRequest request){
        ParamDto result = new ParamDto();
        //需要知道导入的内容是普通表单内容,还是上传文件内容,具体看上次也就详细说明;
        //ServletFileUpload.isMultipartContent 判断前端返回的类型是否是 enctype="multipart/form-data"
        if(ServletFileUpload.isMultipartContent(request))
        {
            //是上传文件类型
            ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
            upload.setHeaderEncoding("UTF-8");
            try {
                /*
                    进行请求的解析,传回数据是 List... FileItem...,
                    里面存储的是所有上传的内容
                    下面数据内容直接打印是不行的需要上传到一个map数组里面然后回发给前端进行使用,则使用dto进行数组内容封装;
                */
                List<FileItem> fileItemList = upload.parseRequest(request);
                //需要看拿到的是什么数据
                for(FileItem fileItem:fileItemList){
                    if(fileItem.isFormField()) {
                        //判断是否是普通表单,是走这里,getFieldName控件name
                        result.getParaMap().put(fileItem.getFieldName(),fileItem.getString("UTF-8"));
                        //System.out.println(fileItem.getFieldName() + ",标题内容:" + fileItem.getString("UTF-8"));
                    }else {
                        result.getFileMap().put(fileItem.getFieldName(),fileItem);
                        //System.out.println("文件名字:"+fileItem.getFieldName());
                        //进行文件内容存储,这是文件流,getName获取文件名;
                        fileItem.write(new File(SAVE_PATH + fileItem.getName()));
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }else {
            //不是上传文件类型,普通表单使用request.getParameter();
            //request.getParameter();
        }
        return result;
    }
}

代码中有详细注释,如果是文件就进行存储否则就进行取值;
前端传回来的不只是文件,还有一些输入框内容,比如标题…那我们就需要进行这几个内容的存值,则就需要进行定义操作;

package com.java.dto;

import org.apache.commons.fileupload.FileItem;

import java.util.HashMap;
import java.util.Map;

/**
 * 对数据流进行存储的封装
 */
public class ParamDto {
    private Map<String,String> ParaMap;//数据流封装
    private Map<String, FileItem> fileMap;//文件流存储
//编写构造方法方便直接调用
    public ParamDto(){
        ParaMap = new HashMap<>();
        fileMap = new HashMap<>();
    }
    public Map<String, String> getParaMap() {
        return ParaMap;
    }

    public void setParaMap(Map<String, String> paraMap) {
        ParaMap = paraMap;
    }

    public Map<String, FileItem> getFileMap() {
        return fileMap;
    }

    public void setFileMap(Map<String, FileItem> fileMap) {
        this.fileMap = fileMap;
    }
}

对数据流进行存储操作,如果是数据则存储数据,如果是文件流则存储文件;

这时候已经明确前端request里面发送过来几个什么值,也需要进行一个封装操作;我这边是一个标题和文件;便于后面的调用,然后就可以把ParamDto 里面的数据准确存储到里面用于调用;

package com.java.dto;

import org.apache.commons.fileupload.FileItem;

/**
 * 这边是做明确传入内容的模块化内容进行对象的存储
 */
public class ImportExcelParamDto {
    private String title;
    private FileItem fileItem;

    public  ImportExcelParamDto(){
    }

    public ImportExcelParamDto(String title, FileItem fileItem) {
        this.title = title;
        this.fileItem = fileItem;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public FileItem getFileItem() {
        return fileItem;
    }

    public void setFileItem(FileItem fileItem) {
        this.fileItem = fileItem;
    }
}

这边做存储演示,不管它;

 			//明确导入内容进行一个存储值操作
            ImportExcelParamDto importExcelParamDto = new ImportExcelParamDto();
            importExcelParamDto.setTitle(dto.getParaMap().get("title"));
            importExcelParamDto.setFileItem(dto.getFileMap().get("excel"));

3.利用POI进行文件的解析读写操作

方法一:在本地生成文件,这种方式比较少

package com.java.Service;

import com.java.Model.ExcelDataList;
import com.java.dto.ImportExcelParamDto;
import com.java.dto.importExcelResult;
import com.java.util.FileHelper;
import org.apache.commons.fileupload.FileItem;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 对excel上次内容进行解析
 */
public class ExcelService {
    /**
     * 明确传入内容,进行一个数据模块存储操作,返回值是一个导入结果类;
     * @param dto
     */
    public importExcelResult imp(ImportExcelParamDto dto){
        //需要使用POI进行操作,进行excel或word的读写操作;
        //获取文件,文件保存地址也不应该是写死的,则需要一个文件保存帮助类来完成
        importExcelResult result = new importExcelResult();//做一个导入结果返回值
        result.setTitle(dto.getTitle());
        String FileName = null;
        //多个值存在List中
        List<ExcelDataList> excelDataLists = new ArrayList<>();
        result.setLists(excelDataLists);
        try {
            FileName = FileHelper.save(dto.getFileItem());
        }catch (Exception ex){
            ex.printStackTrace();
            //发生错误的时候,通知页面
            result.setMsg("保存上传文件失败");
        }
        if(FileName != null) {
            try {
                Workbook workbook = WorkbookFactory.create(new File(FileName));
                Sheet sheet = workbook.getSheetAt(0);//第几个文件夹
                int rowNums = sheet.getLastRowNum();//获取总共多少行
                for (int i = 1; i <= rowNums; i++) {//不从第一行开始,从第二行开始,第一行一般为标题行
                    Row row = sheet.getRow(i);
                    ExcelDataList ex = new ExcelDataList();
                    ex.setName(row.getCell(0).getStringCellValue());
                    ex.setAge((int)row.getCell(1).getNumericCellValue());
                    ex.setTime(row.getCell(2).getDateCellValue());
                    excelDataLists.add(ex);
//                    System.out.println("姓名:" + row.getCell(0).getStringCellValue());//字符串值
//                    System.out.println("年龄:" + row.getCell(1).getNumericCellValue());//数字值
//                    System.out.println("时间:" + row.getCell(2).getDateCellValue());//时间值
                }
            } catch (IOException | InvalidFormatException iex) {
                iex.printStackTrace();
                result.setMsg("解析Excel失败");
            }
        }
        return result;
    }
}

方法二:文件不落地,也就是解析文件内容,但是不在本地生成文件;其实没有什么特别之处就是利用NPO提供的fileItem进行文件流的读取这样不会在本地生成excel文件,也可以获取内容;

package com.java.Service;

import com.java.Model.ExcelDataList;
import com.java.dto.ImportExcelParamDto;
import com.java.dto.importExcelResult;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 对excel上次内容进行解析
 */
public class ExcelService {
    /**
     * 明确传入内容,进行一个数据模块存储操作,返回值是一个导入结果类;
     * @param dto
     */
    public importExcelResult imp(ImportExcelParamDto dto){
        //需要使用POI进行操作,进行excel或word的读写操作;
        //获取文件,文件保存地址也不应该是写死的,则需要一个文件保存帮助类来完成
        importExcelResult result = new importExcelResult();//做一个导入结果返回值
        result.setTitle(dto.getTitle());
        String FileName = null;
        //多个值存在List中
        List<ExcelDataList> excelDataLists = new ArrayList<>();
        result.setLists(excelDataLists);

        Workbook workbook = null;
        try {
            //实现第二种不需要保存文件,直接使用文件流读取,这种方式比较好一点,也就是需要使用fileItem的原因
            workbook = WorkbookFactory.create(dto.getFileItem().getInputStream());//拿到文件流
            Sheet sheet = workbook.getSheetAt(0);//第几个文件夹
            int rowNums = sheet.getLastRowNum();//获取总共多少行
            for (int i = 1; i <= rowNums; i++) {//不从第一行开始,从第二行开始,第一行一般为标题行
                Row row = sheet.getRow(i);
                ExcelDataList ex = new ExcelDataList();
                ex.setName(row.getCell(0).getStringCellValue());
                ex.setAge((int)row.getCell(1).getNumericCellValue());
                ex.setTime(row.getCell(2).getDateCellValue());
                excelDataLists.add(ex);
            }
        } catch (IOException | InvalidFormatException iex) {
            iex.printStackTrace();
            result.setMsg("解析Excel失败");
        }finally {
            if(workbook != null){
                try {
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
}

对上面代码进行说明,首先返回一个结果值,这个结果值主要是用于前端的调用,已经对List进行封装:
详细代码:

package com.java.dto;

import com.java.Model.ExcelDataList;

import java.util.List;

/**
 * 做一个导入结果返回
 */
public class importExcelResult {
    private String title;
    private List<ExcelDataList> lists;
    private String msg;//发生错误的时候返回内容

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<ExcelDataList> getLists() {
        return lists;
    }

    public void setLists(List<ExcelDataList> lists) {
        this.lists = lists;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

定义对象内容:如果说不懂List或者Map可能得去加强一下;

package com.java.Model;

import java.util.Date;

/**
 * 实例化excel导入内容类,存储在对象中
 */
public class ExcelDataList {
    private String name;
    private Date time;
    private Integer age;

    public ExcelDataList() {
    }

    public String getName() {
        return name;
    }

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

    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

上面这样就能准确得到值了。
这边有几个帮助类,要说明一下:
1.文件帮助类:用于对文件地址的获取,存储,以及避免重复名的操作:

package com.java.util;

import org.apache.commons.fileupload.FileItem;

import java.io.File;
import java.util.Date;

/**
 * 文件保存帮助类
 */
public class FileHelper {
    /**
     * 做文件的存储操作,返回一个路径给其调用
     * @param fileItem
     * @param path
     * @return
     */
    private static final String SAVE_PATH = "K:/JavawebExportDown/web/import/";
    public static String save(FileItem fileItem) {
        //用时间戳来去除相同文件名的可能
        String savePath = SAVE_PATH + new Date().getTime() + fileItem.getName() ;
        try {
            fileItem.write(new File(savePath));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return savePath;
    }
}

4.进行Servlet总的调用;

也就是前端submit提交表单的时候第一次进入的地方:

package com.java.servlet;

import com.java.Service.ExcelService;
import com.java.dto.ImportExcelParamDto;
import com.java.dto.ParamDto;
import com.java.dto.importExcelResult;
import com.java.util.RequestHelper;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * 进行对导入文件的处理
 */
public class ImportExcelHandleServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if(ServletFileUpload.isMultipartContent(request)) {
            //文件上传解析,调用封装类;
            ParamDto dto = RequestHelper.parseParam(request);
            //明确导入内容进行一个存储值操作
            ImportExcelParamDto importExcelParamDto = new ImportExcelParamDto();
            importExcelParamDto.setTitle(dto.getParaMap().get("title"));
            importExcelParamDto.setFileItem(dto.getFileMap().get("excel"));
            //接下来对上传的文件进行解析操作;
            ExcelService service = new ExcelService();
            importExcelResult resultDto = service.imp(importExcelParamDto);
            //最后调用给前端
            request.setAttribute("excelList", resultDto);
        }else {
            //request.getParameter();
        }
        request.getRequestDispatcher("/WEB-INF/jsp/importExcelResult.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

前端的使用,采用EL,JSTL进行调用:

在这里插入图片描述
需要引入:
在这里插入图片描述
这样就可以进行批量的导入操作了;
在这里插入图片描述

关于Excel导出功能的编写

相比之下,导出功能会比导入功能处理的要容易很多,基本在导入功能上面进行一系列的处理;
这边服务请求就不重复说明了,配置servlet,在web.xml配置好路径,然后进行请求;
导出功能编写:

package com.java.Service;

import com.java.Model.ExcelDataList;
import com.java.dto.ImportExcelParamDto;
import com.java.dto.importExcelResult;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 对excel上次内容进行解析
 */
public class ExcelService {
    /**
     * 实现导出功能; 设计导出样式可以后期进行设计
     */
    public static Workbook  exportExcel(boolean isXlsx){
        //workbook -- > sheet -- > row -- > cell 处理顺序
        Workbook workbook;
        //解析中要分辨是xls/xlsx;
        if(isXlsx)
            workbook = new XSSFWorkbook();
        else
            workbook =new HSSFWorkbook();
        Sheet sheet = workbook.createSheet("sheet");
        List<List<String>> content = getContent();
        for (int i = 0; i < content.size(); i++) {
            Row row = sheet.createRow(i);
            //然后进行内容的填充也就是cell
            List<String> listData = content.get(i);
            for(int j = 0; j < listData.size(); j ++){
                //识别出有多少个数据
               row.createCell(j).setCellValue(listData.get(j));
            }
        }
        return workbook;
    }

    /**
     * 数据样式,没用数据库直接写死;做数据测试
     * @return
     */
    private static List<List<String>> getContent(){
        List<String> row = new ArrayList<>();//创建行内容,因为没有连接数据库所以直接采用写死方法
        List<List<String>> result = new ArrayList<>();//result是用来统筹List<row>
        row.add("序号");
        row.add("姓名");
        row.add("年龄");
        row.add("爱好");
        //因为需要分行则需要分开写,然后在把List存在list中
        result.add(row);

        row = new ArrayList<>();
        row.add("1");
        row.add("XXXIERW");
        row.add("20");
        row.add("backetball");
        //因为需要分行则需要分开写,然后在把List存在list中
        result.add(row);

        row = new ArrayList<>();
        row.add("2");
        row.add("XXXIERW1");
        row.add("21");
        row.add("backetball1");
        //因为需要分行则需要分开写,然后在把List存在list中
        result.add(row);

        row = new ArrayList<>();
        row.add("3");
        row.add("XXXIERW2");
        row.add("22");
        row.add("backetball2");
        //因为需要分行则需要分开写,然后在把List存在list中
        result.add(row);
        return result;
    }
}

返回一个wookbook数据流;然后进行servlet第一道口进行处理:

package com.java.servlet;

import com.java.Service.ExcelService;
import org.apache.commons.fileupload.FileItem;
import org.apache.poi.ss.usermodel.Workbook;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ExportExcelHandleServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //做导出内容操作;
        Workbook workbook = ExcelService.exportExcel(true);
        //然后就需要响应到页面去,这边有两种写法,一个是直接写入数据流不生成本地文件,一个是生成本地文件,
        //方法一:不生成本地文件
        /*
        response.setHeader("Content-Disposition","filename=export.xls");//需要告诉浏览器传回去的内容是什么
        ServletOutputStream outputStream = response.getOutputStream();
        workbook.write(outputStream);
        outputStream.flush();
        outputStream.close();
        workbook.close();
        */
        //方法二:生成本地文件
        response.setHeader("Content-Disposition","filename=export.xls");//需要告诉浏览器传回去的内容是什么
        ServletOutputStream outputStream = response.getOutputStream();
        FileOutputStream fileOutputStream = new FileOutputStream("K:/JavawebExportDown/web/import/export.xls");
        workbook.write(fileOutputStream);//保存文件
        //读取文件
        FileInputStream fileInputStream = new FileInputStream("K:/JavawebExportDown/web/import/export.xls");
        byte[] bytes = new byte[fileInputStream.available()];
        fileInputStream.read(bytes);
        outputStream.write(bytes);
        outputStream.flush();
        outputStream.close();
        workbook.close();

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

这边有两种方法,都是可以实现的第一种是不生成本地文件直接进行导出(建议使用),不会使服务器的内存增加;
第二种方法:在本地生成一个文件,然后进行输出,这边记住配置这个地方:response.setHeader("Content-Disposition","filename=export.xls");//需要告诉浏览器传回去的内容是什么
这个是给浏览器做响应提示用的,有了这个浏览器才会去响应下载流;
文件命名也是可以改的,建议加上时间戳这种方式是最容易实现的;
实现效果:
在这里插入图片描述

关于word的批量导出导入功能;

实际过程和前面类似,不同的是EXCEL导入存的是LIST而word存的应该是content类型;

package com.java.dto;

import com.java.Model.ExcelDataList;

import java.util.List;

/**
 * 做一个导入结果返回,word直接返回文本内容即可
 */
public class importWordResult {
    private String title;
    private String content;
    private String msg;//发生错误的时候返回内容

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

总得调用中心就是调用其内部功能,

package com.java.Service;

import com.java.dto.ImportWordParamDto;
import com.java.dto.importWordResult;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 对word文件进行处理;
 */
public class  WordService {
    public importWordResult impw(ImportWordParamDto dto){
        importWordResult result = new importWordResult();
        result.setTitle(dto.getTitle());
        //这边是03版本的word进行导入解析操作;
        HWPFDocument doc = null;
        try {
            doc = new HWPFDocument(dto.getWord().getInputStream());//这边报错
            result.setContent(doc.getDocumentText().replace("/n","<br/>"));//返回解析内容
        }catch (OfficeXmlFileException ofe){
            ofe.printStackTrace();
            result.setMsg("这可能是个07版本的word");
        }catch(Exception io){
            io.printStackTrace();
            result.setMsg("word文档解析失败,格式不符合");
            return result;
        }finally {
            if(doc != null){
                try {
                    doc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //07版的word解析操作;
        XWPFDocument docx = null;
        try {
            docx = new XWPFDocument(dto.getWord().getInputStream());
            //07版本传的和03版本不同,它是一个一个获取然后拼接;
            //这边是一行一行获取的,不是直接全部获取,所以每一行加个回车
            List<XWPFParagraph> paragraphs = docx.getParagraphs();
            StringBuffer content = new StringBuffer();
            for(int i = 0; i < paragraphs.size(); i++){
                if(i != 0){
                    content.append("<br/>");
                }
                content.append(paragraphs.get(i).getText());//获取文本拼接
            }
            result.setContent(content.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(docx != null){
                try {
                    docx.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return  result;
    }

    /**
     * 进行导出功能的编写,对03版的导出
     */
    public HWPFDocument export03(Map<String,String> replaceContent){
        //这边是03版本的word进行导入解析操作;
        HWPFDocument doc = null;
        try {
            doc = new HWPFDocument(new FileInputStream("K:\\JavawebExportDown\\web\\template\\template_03.doc"));
            Range range = doc.getRange();//随机字符串用来做替换
            //Map<String,String> 用来做替换内容,key和value
            for(Map.Entry<String,String> entry : replaceContent.entrySet()){
                //遍历替换内容
                range.replaceText(entry.getKey(),entry.getValue());
            }
        }catch(Exception io){
            return null;
        }
        return doc;
    }

    public XWPFDocument export07(Map<String,String> replaceContent){
        XWPFDocument docx = null;
        try{
            docx = new XWPFDocument(new FileInputStream("K:\\JavawebExportDown\\web\\template\\template_07.docx"));
            List<XWPFParagraph> paragraphs = docx.getParagraphs();
            for(XWPFParagraph paragraph:paragraphs){
                List<XWPFRun> runs = paragraph.getRuns();//run是一小段格式相同是一小段不同则不是;
                for(XWPFRun run:runs){
                    String str = run.getText(run.getTextPosition());
                    for(Map.Entry<String,String> entry: replaceContent.entrySet()){
                        str = str.replace(entry.getKey(),entry.getValue());
                    }
                    run.setText(str,0);
                }
            }

        }catch (Exception ex){
            return null;
        }
        return docx;
    }
}

进行一个Servlet处理过程进行处理代码,

package com.java.servlet;

import com.java.Service.WordService;
import com.java.dto.ImportWordParamDto;
import com.java.dto.ParamDto;
import com.java.dto.importWordResult;
import com.java.util.RequestHelper;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class importWordHandleServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //word导入处理
        if(ServletFileUpload.isMultipartContent(request)){
            ParamDto pto = RequestHelper.parseParam(request);
            ImportWordParamDto paramDto = new ImportWordParamDto();
            paramDto.setTitle(pto.getParaMap().get("title"));
            paramDto.setWord(pto.getFileMap().get("word"));
            WordService wordService = new WordService();
            importWordResult resultDto = wordService.impw(paramDto);
            request.setAttribute("result",resultDto);
        }else {

        }
        request.getRequestDispatcher("/WEB-INF/jsp/importWordResult.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

package com.java.servlet;

import com.java.Service.WordService;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class WordExportServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        WordService wordService = new WordService();
        Map<String,String> map = new HashMap<>();
        map.put("${name}",request.getParameter("title"));
        map.put("${age}",request.getParameter("age"));
        map.put("${time}",request.getParameter("time"));
        ServletOutputStream outputStream = response.getOutputStream();
        //判断是03版本还是07版本
        if(request.getParameter("isDocx") != null && !"".equals("isDocx")){
           XWPFDocument docx = wordService.export07(map);
            response.setHeader("Content-Disposition","attachment;filename=export.doc");
            docx.write(outputStream);
            docx.close();
        }else{
            HWPFDocument doc = wordService.export03(map);
            response.setHeader("Content-Disposition","attachment;filename=export.doc");
            doc.write(outputStream);
            doc.close();
        }
        outputStream.flush();
        outputStream.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

最后实现效果:
在这里插入图片描述
在这里插入图片描述
之后会代码进行打包,主要是作用于学习编写,使用开发工具是idea;
代码下载地址:https://download.csdn.net/download/u010374999/12608675

展开阅读全文
  • 1
    点赞
  • 0
    评论
  • 3
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值