Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何用ApachePOI读取和替换书签值_Java_Tomcat_Ms Word_Apache Poi_Bookmarks - Fatal编程技术网

Java 如何用ApachePOI读取和替换书签值

Java 如何用ApachePOI读取和替换书签值,java,tomcat,ms-word,apache-poi,bookmarks,Java,Tomcat,Ms Word,Apache Poi,Bookmarks,我是ApachePOI的完全新手,我已经尝试过几种方法。我的问题是docx文件中有几个书签,我想替换它们的值 我已经将文本添加到书签中,但之前的值仍然存在 我的代码: InputStream fis = new FileInputStream(fileName); XWPFDocument document = new XWPFDocument(fis); List<XWPFParagraph> paragraphs = document.getParagraphs(); for (

我是ApachePOI的完全新手,我已经尝试过几种方法。我的问题是docx文件中有几个书签,我想替换它们的值

我已经将文本添加到书签中,但之前的值仍然存在

我的代码:

InputStream fis = new FileInputStream(fileName);
XWPFDocument document = new XWPFDocument(fis);
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs)
{
    //Here you have your paragraph; 
    CTP ctp = paragraph.getCTP(); 
    // Get all bookmarks and loop through them 
    List<CTBookmark> bookmarks = ctp.getBookmarkStartList(); 
    for(CTBookmark bookmark : bookmarks) 
    { 
         if(bookmark.getName().equals("Firma1234"))
         {
             System.out.println(bookmark.getName());
             XWPFRun run = paragraph.createRun();
             run.setText(lcFirma);
                      ctp.getDomNode().insertBefore(run.getCTR().getDomNode(), bookmark.getDomNode());
         }
    }   
}
OutputStream out = new FileOutputStream(output);
document.write(out);
document.close();
out.close();    
我的docx文件在以下时间之后:

FirmaTestmark
就像我说的,文本插入到书签值之前,而不是替换它,我如何替换文本

您好

凯文

试试下面的代码

private List<XWPFParagraph> collectParagraphs()
    {
        List<XWPFParagraph> paragraphs = new ArrayList<>();
        paragraphs.addAll(this.document.getParagraphs());

        for (XWPFTable table : this.document.getTables())
        {
            for (XWPFTableRow row : table.getRows())
            {
                for (XWPFTableCell cell : row.getTableCells())
                    paragraphs.addAll(cell.getParagraphs());
            }
        }
        return paragraphs;
    }

    public List<String> getBookmarkNames()
    {
        List<String> bookmarkNames = new ArrayList<>();
        Iterator<XWPFParagraph> paraIter = null;
        XWPFParagraph para = null;
        List<CTBookmark> bookmarkList = null;
        Iterator<CTBookmark> bookmarkIter = null;
        CTBookmark bookmark = null;
        XWPFRun run = null;

        // Get an Iterator for the XWPFParagraph object and step through them
        // one at a time.
        paraIter = collectParagraphs().iterator();
        while (paraIter.hasNext())
        {
            para = paraIter.next();

            // Get a List of the CTBookmark object sthat the paragraph
            // 'contains' and step through these one at a time.
            bookmarkList = para.getCTP().getBookmarkStartList();
            bookmarkIter = bookmarkList.iterator();
            while (bookmarkIter.hasNext())
            {
                bookmark = bookmarkIter.next();
                bookmarkNames.add(bookmark.getName());
            }
        }
        return bookmarkNames;
    }

我还需要设置.docx书签的默认文本字段。我不能这样做,所以,我这样做是为了解决问题:用文本替换包含书签的整个段落。因此,我没有用默认文本填充书签,而是用一个段落来保存书签文本。在我的例子中,.docx最终必须转换成一个.pdf文件,因此没有书签并不重要,但正确文本的存在更重要

以下是我如何使用Apache POI实现的:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.TempFileCreationStrategy;
import org.apache.poi.xdgf.usermodel.section.geometry.RelMoveTo;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.UserDataHandler;

/**
 * 
 * @author binita.bharati@gmail.com
 * 
 * This code will replace bookmark with plain text. A bookmark is seen as "Text Form Field" in a .docx file.
 *
 */


public class BookmarkReplacer {

    public static void main(String[] args) throws Exception {
        replaceBookmark();

    }

    private static String replaceBookmarkedPara(String input, String bookmarkTxt) {
        char[] tmp = input.toCharArray();
        StringBuilder sb = new StringBuilder();
        int bookmarkedCharCount = 0;
        for (int i = 0 ; i < tmp.length ; i++) {
            int asciiCode = tmp[i];
            if (asciiCode == 8194) {
                bookmarkedCharCount ++;
                if (bookmarkedCharCount == 5) {
                    sb.append(bookmarkTxt);
                }
            }
            else {
                sb.append(tmp[i]);
            }
        }
        return sb.toString();
    }

    private static void removeAllRuns(XWPFParagraph paragraph) {
        int size = paragraph.getRuns().size();
        for (int i = 0; i < size; i++) {
            paragraph.removeRun(0);
        }
    }

    private static void insertReplacementRuns(XWPFParagraph paragraph, String replacedText) {
        String[] replacementTextSplitOnCarriageReturn = StringUtils.split(replacedText, "\n");

        for (int j = 0; j < replacementTextSplitOnCarriageReturn.length; j++) {
            String part = replacementTextSplitOnCarriageReturn[j];

            XWPFRun newRun = paragraph.insertNewRun(j);
            newRun.setText(part);

            if (j+1 < replacementTextSplitOnCarriageReturn.length) {
                newRun.addCarriageReturn();
            }
        }       
    }

    public static void replaceBookmark () throws Exception 
    {
    InputStream fis = new FileInputStream("C:\\input.docx");
    XWPFDocument document = new XWPFDocument(fis);
    List<XWPFParagraph> paragraphs = document.getParagraphs();
    for (XWPFParagraph paragraph : paragraphs)
    {
        //Here you have your paragraph; 
        CTP ctp = paragraph.getCTP(); 
        // Get all bookmarks and loop through them 
        List<CTBookmark> bookmarks = ctp.getBookmarkStartList(); 
        for(CTBookmark bookmark : bookmarks) 
        { 
             if(bookmark.getName().equals("data_incipit") || bookmark.getName().equals("incipit_Codcli")
                     || bookmark.getName().equals("Incipit_titolo"))
             {

                 String paraText = paragraph.getText();
                 System.out.println("paraText = "+paraText +" for bookmark name "+bookmark.getName());
                 String replacementText = replaceBookmarkedPara(paraText, "haha");
                 removeAllRuns(paragraph);
                 insertReplacementRuns(paragraph, replacementText);

             }
        }   
    }
    OutputStream out = new FileOutputStream("C:\\output.docx");
    document.write(out);
    document.close();
    out.close();  
}
}

我是误读了什么,还是你的代码只是得到了所有的书签名?替换书签值的部分在哪里?
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.TempFileCreationStrategy;
import org.apache.poi.xdgf.usermodel.section.geometry.RelMoveTo;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.UserDataHandler;

/**
 * 
 * @author binita.bharati@gmail.com
 * 
 * This code will replace bookmark with plain text. A bookmark is seen as "Text Form Field" in a .docx file.
 *
 */


public class BookmarkReplacer {

    public static void main(String[] args) throws Exception {
        replaceBookmark();

    }

    private static String replaceBookmarkedPara(String input, String bookmarkTxt) {
        char[] tmp = input.toCharArray();
        StringBuilder sb = new StringBuilder();
        int bookmarkedCharCount = 0;
        for (int i = 0 ; i < tmp.length ; i++) {
            int asciiCode = tmp[i];
            if (asciiCode == 8194) {
                bookmarkedCharCount ++;
                if (bookmarkedCharCount == 5) {
                    sb.append(bookmarkTxt);
                }
            }
            else {
                sb.append(tmp[i]);
            }
        }
        return sb.toString();
    }

    private static void removeAllRuns(XWPFParagraph paragraph) {
        int size = paragraph.getRuns().size();
        for (int i = 0; i < size; i++) {
            paragraph.removeRun(0);
        }
    }

    private static void insertReplacementRuns(XWPFParagraph paragraph, String replacedText) {
        String[] replacementTextSplitOnCarriageReturn = StringUtils.split(replacedText, "\n");

        for (int j = 0; j < replacementTextSplitOnCarriageReturn.length; j++) {
            String part = replacementTextSplitOnCarriageReturn[j];

            XWPFRun newRun = paragraph.insertNewRun(j);
            newRun.setText(part);

            if (j+1 < replacementTextSplitOnCarriageReturn.length) {
                newRun.addCarriageReturn();
            }
        }       
    }

    public static void replaceBookmark () throws Exception 
    {
    InputStream fis = new FileInputStream("C:\\input.docx");
    XWPFDocument document = new XWPFDocument(fis);
    List<XWPFParagraph> paragraphs = document.getParagraphs();
    for (XWPFParagraph paragraph : paragraphs)
    {
        //Here you have your paragraph; 
        CTP ctp = paragraph.getCTP(); 
        // Get all bookmarks and loop through them 
        List<CTBookmark> bookmarks = ctp.getBookmarkStartList(); 
        for(CTBookmark bookmark : bookmarks) 
        { 
             if(bookmark.getName().equals("data_incipit") || bookmark.getName().equals("incipit_Codcli")
                     || bookmark.getName().equals("Incipit_titolo"))
             {

                 String paraText = paragraph.getText();
                 System.out.println("paraText = "+paraText +" for bookmark name "+bookmark.getName());
                 String replacementText = replaceBookmarkedPara(paraText, "haha");
                 removeAllRuns(paragraph);
                 insertReplacementRuns(paragraph, replacementText);

             }
        }   
    }
    OutputStream out = new FileOutputStream("C:\\output.docx");
    document.write(out);
    document.close();
    out.close();  
}
}