Android Studio使用POI读取及修改Word文档(.docx格式)

sohot

发布日期: 2019-10-08 13:02:23 浏览量: 39
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

一、说明

上一篇文章(Android Studio使用POI读取及修改Word文档(.doc格式))使用poi对.doc格式的word文档进行了读取和更改,但很多情况下还需要在word文档中插入图片,这时就需要对.docx格式的word进行操作了。

二、实现过程

2.1 制作文书

文书在源代码中可以直接看到,简单说明一下:文书有普通字段、表格、特定位置的图片,又在页眉页脚中加了普通字段和表格,基本满足对于word操作的所有情况。

2.2 导包

还是上篇中poi-3.9压缩资源包中的jar包,对.docx格式文档的操作用到XWPFDocument方法,使用到所有ooxml相关的jar包。

2.3 build配置

这次的build配置有点特殊,特别拿出来截图一下。就像上一篇说的一样,apache的很多配置在安卓是跑不通的,这次导包后,你会遇到方法过多,文件重复,基于jdk1.6以上版本的变异保存等一系列问题,可以按照下面的方法处理。当然不同的android studio版本可能也会有不同的处理方法,可以百度一下。

权限还是储存权限,直接上代码吧,注解的也很详细。

2.4 实现源码

  1. public class MainActivity extends AppCompatActivity {
  2. //创建生成的文件地址
  3. private static final String newPath = "/storage/emulated/0/test.docx";
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_main);
  8. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  9. ActivityCompat.requestPermissions(this, new String[]{
  10. Manifest.permission.WRITE_EXTERNAL_STORAGE,
  11. Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
  12. }
  13. Button go = (Button) findViewById(R.id.go);
  14. go.setOnClickListener(new View.OnClickListener() {
  15. @Override
  16. public void onClick(View v) {
  17. initData();
  18. }
  19. });
  20. }
  21. private void initData() {
  22. Map<String, Object> map = new HashMap<String, Object>();
  23. map.put("$TITLE$", "标题");//$TITLE$只是个标识符,你也可以用${},[]等等
  24. map.put("$TXT1$", "表格第一行");
  25. map.put("$CONTENT1$", "第一行内容");
  26. map.put("$TXT2$", "表格第二行");
  27. map.put("$CONTENT2$", "第二行内容");
  28. map.put("$CONTENT3$", "页脚中的内容");
  29. map.put("$TXT4$", "页脚表格第一行");
  30. map.put("$CONTENT4$", "页脚第一行内容");
  31. map.put("$TXT5$", "页脚表格第二行");
  32. map.put("$CONTENT5$", "页脚第二行内容");
  33. try {
  34. //读取示例文书
  35. InputStream is = getAssets().open("test.docx");
  36. //自定义的XWPFDocument,解决官方版图片不显示问题
  37. CustomXWPFDocument document = new CustomXWPFDocument(is);
  38. //读取段落(一般段落,页眉页脚没办法读取)
  39. List<XWPFParagraph> listParagraphs = document.getParagraphs();
  40. processParagraphs(listParagraphs, map);
  41. //读取页脚
  42. List<XWPFFooter> footerList = document.getFooterList();
  43. processParagraph(footerList, map);
  44. //处理表格
  45. Iterator<XWPFTable> it = document.getTablesIterator();
  46. while (it.hasNext()) {//循环操作表格
  47. XWPFTable table = it.next();
  48. List<XWPFTableRow> rows = table.getRows();
  49. for (XWPFTableRow row : rows) {//取得表格的行
  50. List<XWPFTableCell> cells = row.getTableCells();
  51. for (XWPFTableCell cell : cells) {//取得单元格
  52. if ("$IMG$".equals(cell.getText())) {
  53. //直接插入图片会在文档的最底端,所以要插在固定位置,要把图片放在表格里
  54. //所以使用判断单元格,并清除单元格放置图片的方式来实现图片定位
  55. cell.removeParagraph(0);
  56. XWPFParagraph pargraph = cell.addParagraph();
  57. document.addPictureData(getAssets().open("1.png"), XWPFDocument.PICTURE_TYPE_PNG);
  58. document.createPicture(document.getAllPictures().size() - 1, 120, 120, pargraph);
  59. }
  60. List<XWPFParagraph> paragraphListTable = cell.getParagraphs();
  61. processParagraphs(paragraphListTable, map);
  62. }
  63. }
  64. }
  65. FileOutputStream fopts = new FileOutputStream(newPath);
  66. document.write(fopts);
  67. if (fopts != null) {
  68. fopts.close();
  69. }
  70. } catch (Exception e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. //处理页脚中的段落,其实就是用方法读取了下页脚中的内容,然后也会当做一般段落处理
  75. private void processParagraph(List<XWPFFooter> footerList, Map<String, Object> map) {
  76. if (footerList != null && footerList.size() > 0) {
  77. for (XWPFFooter footer : footerList) {
  78. //读取一般段落
  79. List<XWPFParagraph> paragraphs = footer.getParagraphs();
  80. processParagraphs(paragraphs, map);
  81. //处理表格
  82. List<XWPFTable> tables = footer.getTables();
  83. for (int i = 0; i < tables.size(); i++) {
  84. XWPFTable xwpfTable = tables.get(i);
  85. List<XWPFTableRow> rows = xwpfTable.getRows();
  86. for (XWPFTableRow row : rows) {//取得表格的行
  87. List<XWPFTableCell> cells = row.getTableCells();
  88. for (XWPFTableCell cell : cells) {//取得单元格
  89. List<XWPFParagraph> paragraphListTable = cell.getParagraphs();
  90. processParagraphs(paragraphListTable, map);
  91. }
  92. }
  93. }
  94. }
  95. }
  96. }
  97. //处理段落
  98. public static void processParagraphs(List<XWPFParagraph> paragraphList, Map<String, Object> param) {
  99. if (paragraphList != null && paragraphList.size() > 0) {
  100. for (XWPFParagraph paragraph : paragraphList) {
  101. List<XWPFRun> runs = paragraph.getRuns();
  102. for (XWPFRun run : runs) {
  103. String text = run.getText(0);
  104. if (text != null) {
  105. boolean isSetText = false;
  106. for (Map.Entry<String, Object> entry : param.entrySet()) {
  107. String key = entry.getKey();
  108. if (text.indexOf(key) != -1) {
  109. isSetText = true;
  110. Object value = entry.getValue();
  111. if (value instanceof String) {//文本替换
  112. text = text.replace(key, value.toString());
  113. }
  114. }
  115. }
  116. if (isSetText) {
  117. run.setText(text, 0);
  118. }
  119. }
  120. }
  121. }
  122. }
  123. }
  124. }

2.5 效果展示

本文转载自:https://blog.csdn.net/qq_21972583/article/details/82740281

上传的附件 cloud_download XWPFDocument.7z ( 10.29mb, 1次下载 )

发送私信

我想要你幸福,但我希望我是你幸福的原因

17
文章数
13
评论数
最近文章
eject