700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android word文档 poi 表格 段落使用记录

Android word文档 poi 表格 段落使用记录

时间:2020-05-31 13:09:22

相关推荐

Android word文档 poi 表格 段落使用记录

需求:Android端根据数据,生成word保存到本地.

查了一些资料好像android 没什么正式的word操作库,基本都是用Java API,Apache POI实现的,但是这个版本比较多android这边兼容不太好,坑比较多…

这边本来是需要word操作雷达图,折线图,柱状图这个些的,需要POI4.x版本,各种姿势依赖,好像都问题,编译或者运行各种不行(可能本人太菜…),没办法只能用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.根据模版生成新的word

模版我是放在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_RIGHTparagraph.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);//生成新的wordFile 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);//生成新的wordFile 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.测试

创建空白word,写入标题 段落,表格

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);

运行结果.

根据模版生成新的word

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();}

模版:

替换之后:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。