Word内容修改,以及转PDF

Word模板内容修改

转自:https://www.cnblogs.com/zwcry/p/8052602.html

1.java代码

 

package com.sicdt.sicsign.web.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.converter.core.XWPFConverterException;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
/**
 * 
 * @author zhenwei.shi
 *
 */
public class DocxUtils {
    //word模板的标签为【string】
    private static final String FLAG_L = "【";//标签左侧
    private static final String FLAG_R = "】";//标签右侧
    //private static final String REGEX = "(\\w|\\W)*\\【\\w+\\】(\\w|\\W)*";//正则匹配*【*】*类型字符串
    public static final String NULL_REPLACE = "   /   ";//如果没有替换的将显示"  "
    public static final String DOWNLOAD_REPLACE =  "      ";//下载替换word模板标签
    public static final String PREVIEW_REPLACE =  "   /   ";//预览替换word模板标签
    /**
     * <br>
     * 描 述: doc内容改变 <br>
     * 作 者: shizhenwei <br>
     * 历 史: (版本) 作者 时间 注释
     * 
     * @param is
     *            doc文档模板
     * @param params
     *            key value 将模板里的可以替换为响应VALUE
     * @return
     * @throws IOException
     */
    public static byte[] docContentChange(InputStream is, Map<String, String> params) throws IOException {
        if(null==params){
            params = new HashMap<String,String>();
        }
        HWPFDocument document = new HWPFDocument(is);
        Range range = document.getRange();

        Set<String> keys = params.keySet();
        for (String key : keys) {
            range.replaceText(key.toString(), params.get(key));
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        document.write(baos);
        byte[] bytes = baos.toByteArray();

        document.close();
        baos.close();
        return bytes;
    }
    
    /**
     * <br>描 述:    改变word内容,讲word标签【*】替换为指定内容
     * <br>作 者: shizhenwei 
     * <br>历 史: (版本) 作者 时间 注释
     * @return
     * @throws IOException 
     * @throws XWPFConverterException 
     */
    public static byte[] docxContentChange(InputStream is,Map<String,String> params) throws XWPFConverterException, IOException{
        return docxContentChange(is,params,NULL_REPLACE);
    }
    
    
    
    /**
     * <br>描 述: docx内容改变
     * <br>作 者: shizhenwei 
     * <br>历 史: (版本) 作者 时间 注释
     * @param is    docx文档模板
     * @param params key value 将模板里的可以替换为响应VALUE
     * @return
     * @throws IOException 
     * @throws XWPFConverterException 
     */
    public static byte[] docxContentChange(InputStream is,Map<String,String> params,String replace) throws XWPFConverterException, IOException{
        if(null==params){
            params = new HashMap<String,String>();
        }
        XWPFDocument document = new XWPFDocument(is);
        //替换段落内容
        List<XWPFParagraph> list = document.getParagraphs();
        for(XWPFParagraph paragraph : list){
            replaceParagraph(paragraph, params, replace,true);
        }
        
        //替换表格内容
        List<XWPFTable> tableList = document.getTables();
        for(XWPFTable table : tableList){
            List<XWPFTableRow> rows = table.getRows();
             for (XWPFTableRow row : rows) {
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    List<XWPFParagraph> paras = cell.getParagraphs();
                    for (XWPFParagraph para : paras) {
                        replaceParagraph(para, params, replace,false);
                    }
                }
             }
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        document.write(baos);
        byte[] bytes = baos.toByteArray();
        document.close();
        baos.close();
        return bytes;
    }
    
    /**
     * <br>描 述:    将docx字节数组流转换为pdf字节数组流
     * <br>作 者: shizhenwei 
     * <br>历 史: (版本) 作者 时间 注释
     * @param docxBytes docx文档字节数组
     * @return
     * @throws XWPFConverterException
     * @throws IOException
     * 注:需在部署系统安装word对应的中文字体
     */
    public static byte[] docx2pdf(byte[] docxBytes) throws XWPFConverterException, IOException{
        PdfOptions options = PdfOptions.create();
        XWPFDocument document = new XWPFDocument(new ByteArrayInputStream(docxBytes));
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfConverter.getInstance().convert(document, baos, options);
        return baos.toByteArray();
    }
    
    
    /**
     * <br>描 述:    将Word模板流改变内容后转换为pdf字节数组流
     * <br>作 者: shizhenwei 
     * <br>历 史: (版本) 作者 时间 注释
     * @param is docx文档输入流
     * @param params key value 将模板里的可以替换为响应VALUE
     * @return
     * @throws IOException 
     * @throws XWPFConverterException 
     * * 注:需在部署系统安装word对应的中文字体
     */
    public static byte[] docx2pdf(InputStream is,Map<String, String> params,String replace) throws XWPFConverterException, IOException{
        if(null==params){
            params = new HashMap<String,String>();
        }
        XWPFDocument document = new XWPFDocument(is);
        //替换段落内容
        List<XWPFParagraph> list = document.getParagraphs();
        for(XWPFParagraph paragraph : list){
            replaceParagraph(paragraph, params, replace,true);
        }
        
        //替换表格内容
        List<XWPFTable> tableList = document.getTables();
        for(XWPFTable table : tableList){
            List<XWPFTableRow> rows = table.getRows();
             for (XWPFTableRow row : rows) {
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    List<XWPFParagraph> paras = cell.getParagraphs();
                    for (XWPFParagraph para : paras) {
                        replaceParagraph(para, params, replace,false);
                    }
                }
             }
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfOptions options = PdfOptions.create();
        PdfConverter.getInstance().convert(document, baos, options);
        byte[] bytes = baos.toByteArray();
        document.close();
        baos.close();
        return bytes;
    }
    
    //在替换的值左右延长两个空格长度
    public static String getReplaceValue(String old){
        return " "+old+" ";
    }
    /**
     * <br>描 述: 替换段落内容
     * <br>作 者: shizhenwei 
     * <br>历 史: (版本) 作者 时间 注释
     * @param paragraph
     * @param params
     * @param replace
     * @param underline
     * @return
     */
    public static String replaceParagraph(XWPFParagraph paragraph,Map<String, String> params,String replace,boolean underline){
        //字符串过长,调用matches方法报堆溢出错误
        /*String regex = REGEX;//【string】匹配
        if(!paragraph.getText().matches(regex)){
            continue;
        }*/
        //改为contains
        String pghTxt = paragraph.getText();
        if(!(pghTxt.contains(FLAG_L)&&pghTxt.contains(FLAG_R))){
            return null;
        }
        List<XWPFRun> runs = paragraph.getRuns();
        String key = "";
        boolean left = false;//left=true 说明有【
        boolean right = false;//right=true 说明有】
        //这里没有做到百分百细致化,如果run中出现这样的形式 *【*】*】或者*】*【*】,将会存在问题,所以要监管好模板。
        for(int i=0; i<runs.size(); i++){
            XWPFRun run = runs.get(i);
            String runText = run.text();
            if(runText.contains(FLAG_L) && runText.contains(FLAG_R)){
                key = runText.substring(runText.indexOf(FLAG_L)+1,runText.indexOf(FLAG_R));
                String text = runText.replaceAll(FLAG_L+key+FLAG_R, StringUtils.isEmpty(params.get(key))?replace:getReplaceValue(params.get(key)));
                run.setText(text,0);
                key = "";
                addUnderline(run, underline);
            }else if(runText.contains(FLAG_L)){
                left = true;
                String temp = runText.substring(runText.indexOf(FLAG_L)+1);
                key += temp;
                String text = runText.replaceAll(FLAG_L+temp, "");
                run.setText(text,0);
                addUnderline(run, underline);
            }else if(runText.contains(FLAG_R)){
                right = true;
                String temp = runText.substring(0,runText.indexOf(FLAG_R));
                key += temp;
                String text = runText.replaceAll(temp+FLAG_R, (StringUtils.isEmpty(params.get(key))?replace:getReplaceValue(params.get(key))));
                run.setText(text,0);
                key = "";
                left = false;
                right = false;
                addUnderline(run, underline);
            }else{
                if(left==true && right==false){
                    key += runText;
                    run.setText("",0);
                    addUnderline(run, underline);
                }
                if(left==false){
                    continue;
                }
            }
        }
        return StringUtils.isEmpty(params.get(key))?replace:getReplaceValue(params.get(key));
    }
    
    /**
     * <br>描 述: 添加下划线
     * <br>作 者: shizhenwei 
     * <br>历 史: (版本) 作者 时间 注释
     * @param run
     * @param underline
     * @return
     */
    public static XWPFRun addUnderline(XWPFRun run,boolean underline){
        //是否添加下划线
        if(underline){
            run.setUnderline(UnderlinePatterns.SINGLE);
        }else{
            run.setUnderline(UnderlinePatterns.NONE);
        }
        return run;
    }
}

复制代码

 

复制代码

package com.sicdt.sicsign.web.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import org.apache.poi.xwpf.converter.core.XWPFConverterException;

public class WordUtils {

    /**
     * <br>
     * 描 述: doc内容改变 <br>
     * 作 者: shizhenwei <br>
     * 历 史: (版本) 作者 时间 注释
     * 
     * @param is
     *            doc文档模板
     * @param params
     *            key value 将模板里的可以替换为响应VALUE
     * @return
     * @throws IOException
     */
    public static byte[] docContentChange(InputStream is, Map<String, String> params) throws IOException {
        return DocxUtils.docContentChange(is, params);
    }

    /**
     * <br>
     * 描 述: docx内容改变 <br>
     * 作 者: shizhenwei <br>
     * 历 史: (版本) 作者 时间 注释
     * 
     * @param is
     *            docx文档模板
     * @param params
     *            key value 将模板里的可以替换为响应VALUE
     * @return
     * @throws IOException
     * @throws XWPFConverterException
     */
    public static byte[] docxContentChange(InputStream is, Map<String, String> params)
            throws XWPFConverterException, IOException {
        return DocxUtils.docxContentChange(is, params);
    }
    
    /***
     * <br>
     * 描 述: docx内容预览 <br>
     * 作 者: zhaowei <br>
     * 历 史: (版本) 作者 时间 注释
     * 
     * @param is
     * @param params
     * @return
     * @throws XWPFConverterException
     * @throws IOException
     */
    public static byte[] docxContentChangeView(InputStream is, Map<String, String> params)
            throws XWPFConverterException, IOException {
        return DocxUtils.docxContentChange(is, params,DocxUtils.PREVIEW_REPLACE);
    }
    
    /***
     * <br>
     * 描 述: docx内容预览 <br>
     * 作 者: zhaowei <br>
     * 历 史: (版本) 作者 时间 注释
     * 
     * @param is
     * @param params
     * @return
     * @throws XWPFConverterException
     * @throws IOException
     */
    public static byte[] docxContentChangeDownload(InputStream is, Map<String, String> params)
            throws XWPFConverterException, IOException {
        return DocxUtils.docxContentChange(is, params,DocxUtils.DOWNLOAD_REPLACE);
    }

    /**
     * <br>
     * 描 述: 将docx字节数组流转换为pdf字节数组流 <br>
     * 作 者: shizhenwei <br>
     * 历 史: (版本) 作者 时间 注释
     * 
     * @param docxBytes
     *            docx文档字节数组
     * @return
     * @throws XWPFConverterException
     * @throws IOException
     *             注:需在部署系统安装word对应的中文字体
     */
    public static byte[] docx2pdf(byte[] docxBytes) throws XWPFConverterException, IOException {
        return DocxUtils.docx2pdf(docxBytes);
    }

    /**
     * <br>
     * 描 述: 将Word模板流改变内容后转换为pdf字节数组流 <br>
     * 作 者: shizhenwei <br>
     * 历 史: (版本) 作者 时间 注释
     * 
     * @param is
     *            docx文档输入流
     * @param params
     *            key value 将模板里的可以替换为响应VALUE
     * @return
     * @throws IOException
     * @throws XWPFConverterException
     *             * 注:需在部署系统安装word对应的中文字体
     */
    public static byte[] docx2pdf(InputStream is, Map<String, String> params)
            throws XWPFConverterException, IOException {
        return DocxUtils.docx2pdf(is, params,DocxUtils.NULL_REPLACE);
    }
}

复制代码

 

2.poi版本

复制代码

<!-- 以下是POI相关使用     注:版本号不可轻易更改 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.14</version>
        </dependency>
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
            <version>1.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.17</version>
        </dependency>

复制代码

3.模板样式

  

 

  

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值