Android word 文書 poi フォーム段落使用記録

要件:Android側でデータを元に単語を生成し、ローカルに保存する
情報を確認したところ、基本的にJava APIとApache POIで実装されているAndroid向けの公式の単語操作ライブラリはないようですが、このバージョンではは Android との互換性が高くなります。 , 落とし穴がたくさんあります.
ここで、レーダーチャート、折れ線グラフ、ヒストグラムなどを操作するには単語が必要です. POI4 が必要です. ...), を使用する方法はありません3.x バージョン、チャートについて話しましょう...

1.gradleはPOIに依存します

app ディレクトリ build.gradle に、完全な依存関係を追加します。


dependencies {
    
    
	...
    implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'
    implementation group: 'org.apache.xmlbeans', name: 'xmlbeans', version: '3.1.0'
    implementation 'javax.xml.stream:stax-api:1.0'
    implementation 'com.fasterxml:aalto-xml:1.2.2'
    ...
    }
2. 新しい段落を追加する
		/**
     * 添加段落内容
     *
     * @param document   word文档对象 XWPFDocument document = new XWPFDocument()
     * @param fontSize   字体大小
     * @param fontFamily 字体类型
     * @param text       标题
     */
    public static void addParagraph(XWPFDocument document, int fontSize, String fontFamily, String text) {
    
    
    	//创建空白word文档
		//XWPFDocument document = new XWPFDocument()
        XWPFParagraph paragraph = document.createParagraph();
        //内容左对齐
        paragraph.setAlignment(ParagraphAlignment.valueOf(STJc.INT_LEFT));
        XWPFRun run = paragraph.createRun();
        run.setFontSize(13);
        run.setFontFamily("黑体");
        run.addTab();
        run.setText(text);
        run.addBreak();
    }
3. 新しいフォームを追加する
  • document.createTable(1, 2);
    1 行 2 列のテーブルを作成します
    table.getRow(0).getCell(0).setText()
    table.getRow(0).getCell(1).setText()
  • document.createTable();
    デフォルトで 1 行 1 列を作成
    table.getRow(0).getCell(0).setText()
    table.getRow(0).addNewTableCell().setText()

 /**
     * 添加表格
     * XWPFDocument document = new XWPFDocument()
     *
     * @param document word文档对象.
     */
    public static void addTable(XWPFDocument document) {
    
    
        //创建表格 1行  list.size 列
        //XWPFTable table = document.createTable(1, 2);
        XWPFTable table = document.createTable();

        CTTbl tTbl = table.getCTTbl();
        CTTblPr tTblPr = tTbl.getTblPr() == null ? tTbl.addNewTblPr() : tTbl.getTblPr();
        CTTblWidth tblWidth = tTblPr.isSetTblW() ? tTblPr.getTblW() : tTblPr.addNewTblW();

        //设置表格宽度
        tblWidth.setType(STTblWidth.DXA);
        tblWidth.setW(new BigInteger("8000"));

        table.getRow(0).setHeight(1000);
        //第一列
        setCellStr(table.getRow(0).getCell(0), "主题一", 3000);
        //setCellStr(table.getRow(0).getCell(1), "孤勇者-陈奕迅", 5000);
        //第二列
        setCellStr(table.getRow(0).addNewTableCell(), "孤勇者-陈奕迅", 5000);

        XWPFTableRow row_1 = table.createRow();
        row_1.setHeight(1000);
        setCellStr(row_1.getCell(0), "主题二", 3000);
        setCellStr(row_1.getCell(1), "再回首-岩贵|再回首恍然如梦", 5000);

        XWPFTableRow row_2 = table.createRow();
        row_2.setHeight(1000);
        setCellStr(row_2.getCell(0), "主题三", 3000);
        setCellStr(row_2.getCell(1), "光辉岁月-黄家驹", 5000);
    }

セル プロパティを設定し
、水平方向のセンタリングに注意してください: これはちょっとした落とし穴で、さらに悪いことです. すべて ctTc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc) です.CENTER);、バージョンの問題を ctTc.getPArray()[0].addNewPPr().addNewJc().setVal(STJc.CENTER); に変更する必要があるため、コンパイルはエラーを報告せず、メソッドはキーコードをクリックすると、この方法があります...

private static void setCellStr(XWPFTableCell cell, String str, int w) {
    
    

        CTTc ctTc = cell.getCTTc();
        CTTcPr ctTcPr = ctTc.addNewTcPr();
        ctTcPr.addNewTcW().setW(BigInteger.valueOf(w));
        //上下居中
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        //水平居中
        //ctTc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
        ctTc.getPArray()[0].addNewPPr().addNewJc().setVal(STJc.CENTER);
        cell.setText(str);
    }
4. テンプレートに従って新しい単語を生成する

テンプレートを assets ディレクトリに置き、フィールドに $ が含まれているかどうかを判断し、必要なものに置き換えます。
ここに画像の説明を挿入

4.1 段落の置き換え
/**
     * 替换段落文本
     *
     * @param document docx解析对象
     * @param textMap  需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap) {
    
    
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();

        for (XWPFParagraph paragraph : paragraphs) {
    
    
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            Log.i(TAG, "changeText:行 " + text);
            if (text.contains("$")) {
    
    
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
    
    
                    //替换模板原来位置
                    Log.i(TAG, "changeText:行内 " + run.getText(run.getTextPosition()));
                    run.setText(changeValue(run.toString(), textMap), 0);
                }
            }
        }

    }
4.2 代替フォーム
  /**
     * 替换表格对象方法
     *
     * @param document docx解析对象
     * @param textMap  需要替换的信息集合
     */
    public static void changeTable(XWPFDocument document, Map<String, String> textMap) {
    
    
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();

        for (int i = 0; i < tables.size(); i++) {
    
    
            Log.i(TAG, "changeTable: 1" + tables.get(i).getText());
            //只处理行数大于等于2的表格,且不循环表头
            XWPFTable table = tables.get(i);
            if (table.getRows().size() > 1) {
    
    
                //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                if (table.getText().contains("$")) {
    
    
                    List<XWPFTableRow> rows = table.getRows();
                    //遍历表格,并替换模板
                    eachTable(rows, textMap);
                }
            }
        }
    }
5. 完全なツール コード
public class PoiWordUtils {
    
    

    private static final String TAG = "";

    /**
     * 添加段落标题
     *
     * @param document   word文档对象 XWPFDocument document = new XWPFDocument()
     * @param fontSize   字体大小
     * @param fontFamily 字体类型
     * @param isBreak    是否换行
     * @param title      标题
     */
    public static void addParagraphTitle(XWPFDocument document, int fontSize, String fontFamily, boolean isBreak, int gravity, String title) {
    
    
        XWPFParagraph paragraph = document.createParagraph();
        //设置段落居中 / STJc.INT_LEFT - STJc.INT_RIGHT
        paragraph.setAlignment(ParagraphAlignment.valueOf(gravity));
        //行间距
        //paragraph.setSpacingBefore(1);
        XWPFRun run = paragraph.createRun();
        run.setFontSize(fontSize);
        run.setFontFamily("宋体");
        run.setBold(true);
        run.setText(title);
        //换行
        if (isBreak)
            run.addBreak();

        run.addTab();
    }

    /**
     * 添加段落内容
     *
     * @param document   word文档对象 XWPFDocument document = new XWPFDocument()
     * @param fontSize   字体大小
     * @param fontFamily 字体类型
     * @param text       标题
     */
    public static void addParagraph(XWPFDocument document, int fontSize, String fontFamily, String text) {
    
    

        XWPFParagraph paragraph = document.createParagraph();
        //内容左对齐
        paragraph.setAlignment(ParagraphAlignment.valueOf(STJc.INT_LEFT));
        XWPFRun run = paragraph.createRun();
        run.setFontSize(13);
        run.setFontFamily("黑体");
        run.addTab();
        run.setText(text);
        run.addBreak();
    }


    /**
     * 添加表格
     * XWPFDocument document = new XWPFDocument()
     *
     * @param document word文档对象.
     */
    public static void addTable(XWPFDocument document) {
    
    
        //创建表格 1行  list.size 列
        //XWPFTable table = document.createTable(1, 2);
        XWPFTable table = document.createTable();

        CTTbl tTbl = table.getCTTbl();
        CTTblPr tTblPr = tTbl.getTblPr() == null ? tTbl.addNewTblPr() : tTbl.getTblPr();
        CTTblWidth tblWidth = tTblPr.isSetTblW() ? tTblPr.getTblW() : tTblPr.addNewTblW();

        //设置表格宽度
        tblWidth.setType(STTblWidth.DXA);
        tblWidth.setW(new BigInteger("8000"));


        table.getRow(0).setHeight(1000);
        //第一列
        setCellStr(table.getRow(0).getCell(0), "主题一", 3000);
        //第二列
        //setCellStr(table.getRow(0).getCell(1), "孤勇者-陈奕迅", 5000);
        setCellStr(table.getRow(0).addNewTableCell(), "孤勇者-陈奕迅", 5000);

        XWPFTableRow row_1 = table.createRow();
        row_1.setHeight(1000);
        setCellStr(row_1.getCell(0), "主题二", 3000);
        setCellStr(row_1.getCell(1), "再回首-岩贵|再回首恍然如梦", 5000);

        XWPFTableRow row_2 = table.createRow();
        row_2.setHeight(1000);
        setCellStr(row_2.getCell(0), "主题三", 3000);
        setCellStr(row_2.getCell(1), "光辉岁月-黄家驹", 5000);
    }


    private static void setCellStr(XWPFTableCell cell, String str, int w) {
    
    

        CTTc ctTc = cell.getCTTc();
        CTTcPr ctTcPr = ctTc.addNewTcPr();
        ctTcPr.addNewTcW().setW(BigInteger.valueOf(w));
        //上下居中
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        //水平居中
        //ctTc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
        ctTc.getPArray()[0].addNewPPr().addNewJc().setVal(STJc.CENTER);
        cell.setText(str);
    }


/**-----------------------------------------模版相关---------------------------------------------**/


    /**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
     *
     * @param inputUrl  模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap   需要替换的信息集合
     * @return 成功返回true, 失败返回false
     */
    public static boolean changWord(String inputUrl, String outputUrl,
                                    Map<String, String> textMap) {
    
    

        //模板转换默认成功
        boolean changeFlag = true;
        try {
    
    
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            changeText(document, textMap);
            //解析替换表格对象
            changeTable(document, textMap);
            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();

        } catch (IOException e) {
    
    
            e.printStackTrace();
            changeFlag = false;
        }

        return changeFlag;

    }


    public static boolean changWord(InputStream is, String outputUrl,
                                    Map<String, String> textMap) {
    
    

        //模板转换默认成功
        boolean changeFlag = true;
        try {
    
    
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(is);
            //解析替换文本段落对象
            changeText(document, textMap);
            //解析替换表格对象
            changeTable(document, textMap);
            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();

        } catch (IOException e) {
    
    
            e.printStackTrace();
            changeFlag = false;
        }

        return changeFlag;

    }


    /**
     * 替换段落文本
     *
     * @param document docx解析对象
     * @param textMap  需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap) {
    
    
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();

        for (XWPFParagraph paragraph : paragraphs) {
    
    
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            Log.i(TAG, "changeText:行 " + text);
            if (text.contains("$")) {
    
    
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
    
    
                    //替换模板原来位置
                    Log.i(TAG, "changeText:行内 " + run.getText(run.getTextPosition()));
                    run.setText(changeValue(run.toString(), textMap), 0);
                }
            }
        }

    }

    /**
     * 替换表格对象方法
     *
     * @param document docx解析对象
     * @param textMap  需要替换的信息集合
     */
    public static void changeTable(XWPFDocument document, Map<String, String> textMap) {
    
    
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();

        for (int i = 0; i < tables.size(); i++) {
    
    
            Log.i(TAG, "changeTable: 1" + tables.get(i).getText());
            //只处理行数大于等于2的表格,且不循环表头
            XWPFTable table = tables.get(i);
            if (table.getRows().size() > 1) {
    
    
                //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                if (table.getText().contains("$")) {
    
    
                    List<XWPFTableRow> rows = table.getRows();
                    //遍历表格,并替换模板
                    eachTable(rows, textMap);
                }
            }
        }
    }


    /**
     * 遍历表格
     *
     * @param rows    表格行对象
     * @param textMap 需要替换的信息集合
     */
    public static void eachTable(List<XWPFTableRow> rows, Map<String, String> textMap) {
    
    
        for (XWPFTableRow row : rows) {
    
    
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
    
    
                Log.i(TAG, "eachTable: 2 " + cell.getText());
                //判断单元格是否需要替换
                if (cell.getText().contains("$")) {
    
    
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
    
    
                        Log.i(TAG, "eachTable: 3" + paragraph.getText());
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
    
    
                            Log.i(TAG, "eachTable: 4 " + run.getText(run.getTextPosition()));
                            run.setText(changeValue(run.toString(), textMap), 0);
                        }
                    }
                }
            }
        }
    }

    /**
     * 匹配传入信息集合与模板
     *
     * @param value   模板需要替换的区域
     * @param textMap 传入信息集合
     * @return 模板需要替换区域信息集合对应值
     */
    public static String changeValue(String value, Map<String, String> textMap) {
    
    
        Set<Map.Entry<String, String>> textSets = textMap.entrySet();
        for (Map.Entry<String, String> textSet : textSets) {
    
    
            //匹配模板与替换值 格式${key}
            String key = "${" + textSet.getKey() + "}";
            if (value.contains(key)) {
    
    
                value = textSet.getValue();
            }
        }
        //模板未匹配到区域替换为空
        if (value.contains("$")) {
    
    
            value = "";
        }
        return value;
    }
}

6. テスト

空白の単語を作成し、タイトルの段落、表を書きます

String path = FileUtils.getAppRootPth(this) + File.separator + "word"
                + File.separator + "测试3.100.docx";

        try (XWPFDocument document = new XWPFDocument(); FileOutputStream fos = new FileOutputStream(path)) {
    
    
            //标题
            PoiWordUtils.addParagraphTitle(document, 20, null,true,STJc.INT_CENTER, "POI段落标题");
            //小标题
            PoiWordUtils.addParagraphTitle(document, 15, null,false,STJc.INT_LEFT, "一丶内容示例");
            //段落
            PoiWordUtils.addParagraph(document, -1, null, "POI是Apache软件" +
                    "基金会用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft" +
                    " Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写," +
                    "意为“简洁版的模糊实现”。\n" +
                    "所以POI的主要功能是可以用Java操作Microsoft Office的相关文件,但是一般我们都是用来操作" +
                    "Excel相关文件。");
            PoiWordUtils.addParagraph(document, -1, null, "POI是Apache软件" +
                    "基金会用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft" +
                    " Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写," +
                    "意为“简洁版的模糊实现”。\n" +
                    "所以POI的主要功能是可以用Java操作Microsoft Office的相关文件,但是一般我们都是用来操作" +
                    "Excel相关文件。");
            PoiWordUtils.addParagraphTitle(document, 15, null,false,STJc.INT_LEFT, "二丶内容示例");
            PoiWordUtils.addParagraph(document, -1, null, "POI是Apache软件" +
                    "基金会用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft" +
                    " Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写," +
                    "意为“简洁版的模糊实现”。\n" +
                    "所以POI的主要功能是可以用Java操作Microsoft Office的相关文件,但是一般我们都是用来操作" +
                    "Excel相关文件。");
            PoiWordUtils.addTable(document);
            //写入本地
            document.write(fos);

実行結果
ここに画像の説明を挿入
テンプレートに従って新しい単語を生成する

Map<String, String> testMap = new HashMap<>();
        testMap.put("Title", "POI模版替换");
        testMap.put("FirstHeading", "规则说明");
        testMap.put("FirstHeadingContent", "1.玩家同一场景,以个人为单位进行战斗.\n2.可以对其他玩家进行攻击\n3.一场游戏时间为10分钟");
        testMap.put("SecondHeading", "奖励说明");
        testMap.put("A", "主题A");
        testMap.put("a", "主题A详情");
        testMap.put("B", "主题B");
        testMap.put("b", "主题B详情");
        testMap.put("C", "主题C");
        testMap.put("c", "主题C详情");
        try {
    
    
            InputStream is = getAssets().open("谈话结果主题摘要模板.docx");
            //InputStream is = getAssets().open("阶段性风险评估报告模版.docx");
            String path = FileUtils.getAppRootPth(this) + File.separator + "word" + File.separator + "测试24.docx";
            //boolean b = WordUtils.changWord(is, path, testMap, testList);
            boolean b = WordUtils.changWord(is, path, testMap);
            Log.i(TAG, "testWord: " + b);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

テンプレート:
ここに画像の説明を挿入
置き換え後:
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_35193677/article/details/129489801