Apache POI或docx4j中的SUM(ABOVE)功能 [英] SUM(ABOVE) functionality in apache poi or docx4j

查看:87
本文介绍了Apache POI或docx4j中的SUM(ABOVE)功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在docx中实现= SUM(ABOVE)函数,该函数用于将以上所有元素加到列中.我能够使用

I am trying to implement =SUM(ABOVE) function in docx which is used to sum all elements above to tht column. I was able to implement this with apache poi using :

    CTSimpleField sumAbove = paragraphInCell.getCTP().addNewFldSimple();
  sumAbove.setInstr("=SUM(ABOVE)");
  //set sum field dirty, so it must be calculated while opening the document
  sumAbove.setDirty(STOnOff.TRUE);

当有人打开文档并对其进行计算时,这是可以的.但是,如果我需要转换文档而不将其打开为pdf,则此功能将无法运行.Aspose具有称为的功能:

This is ok when someone opens the document and it calculates it. But if I need to convert the document without opening it to pdf then this function doesnt run. Aspose has function called :

Document.UpdateFields

具有必需的功能,但这是付费应用程序.

which does the required functionality but this is paid application.

我们可以使用apche poi或docx4j实现相同的功能吗

Can we implement the same functionality using apche poi or docx4j

推荐答案

如果您不想将字段设置为脏,则需要自己计算总和.以下是用于计算 XWPFTable 的特殊列的表单元格值之和的方法的工作草案:

If you don't want set the field dirty, then you need calculating the sum your own. Following is a working draft for a method to calculate the sum of table cell values of a special column of a XWPFTable:

 Double calculateSum(XWPFTable table, int col) {
  Double result = null;
  for (XWPFTableRow row : table.getRows()) {
   if (row.getTableCells().size() > col) {
    XWPFTableCell cell = row.getCell(col);
    String cellContent = cell.getText();
    try {
     Number cellValue = java.text.NumberFormat.getInstance().parse(cellContent);
     if (result == null) result = 0d;
     result += cellValue.doubleValue();
    } catch(Exception ex) {
     //could not parse text to number
     //ex.printStackTrace();
    }
   }
  }
  return result;
 }

如果有总和,则 CTSimpleField 需要获取以总和设置为文本值的文本运行.然后,这与 Word 一样,为字段设置缓存的值.

If you have the sum, then CTSimpleField needs to get a text run having the sum set as text value. Then this the same as Word does to set cached value for the field.

完整示例:

import java.io.FileOutputStream;

import org.apache.poi.xwpf.usermodel.*;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSimpleField;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;

public class CreateWordTableSumAbove {

 static Double calculateSum(XWPFTable table, int col) {
  Double result = null;
  for (XWPFTableRow row : table.getRows()) {
   if (row.getTableCells().size() > col) {
    XWPFTableCell cell = row.getCell(col);
    String cellContent = cell.getText();
    try {
     Number cellValue = java.text.NumberFormat.getInstance().parse(cellContent);
     if (result == null) result = 0d;
     result += cellValue.doubleValue();
    } catch(Exception ex) {
     //could not parse text to number
     //ex.printStackTrace();
    }
   }
  }
  return result;
 }

 static void setText(XWPFTableCell cell, String text) {
  XWPFParagraph par = null;
  if (cell.getParagraphs().size() == 0) par = cell.addParagraph();
  else par = cell.getParagraphs().get(0);
  par.createRun().setText(text);
 }

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

  XWPFDocument document= new XWPFDocument();

  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run=paragraph.createRun();  
  run.setText("The table:");

  //create the table
  XWPFTable table = document.createTable(4,3);
  table.setWidth("100%");
  for (int row = 0; row < 3; row++) {
   for (int col = 0; col < 3; col++) {
    if (col < 2) {
     setText(table.getRow(row).getCell(col), "row " + row + ", col " + col);
    } else {
     setText(table.getRow(row).getCell(col), "" + ((row + 1) * 1234));
    }
   }
  }

  //set Sum row
  setText(table.getRow(3).getCell(0), "Sum:");

  //get paragraph from cell where the sum field shall be contained
  XWPFParagraph paragraphInCell = null;
  if (table.getRow(3).getCell(2).getParagraphs().size() == 0) paragraphInCell = table.getRow(3).getCell(2).addParagraph();
  else paragraphInCell = table.getRow(3).getCell(2).getParagraphs().get(0);

  //set sum field in
  CTSimpleField sumAbove = paragraphInCell.getCTP().addNewFldSimple();
  sumAbove.setInstr("=SUM(ABOVE)");
  Double sum = calculateSum(table, 2);
System.out.println(sum);
  if (sum != null) {
   //if there is a sum, set that sum to be the cached result of the field
   sumAbove.addNewR().addNewT().setStringValue(new java.text.DecimalFormat("#.#").format(sum));
  } else {
   //set sum field dirty, so it must be calculated while opening the document
   sumAbove.setDirty(STOnOff.TRUE);
  }

  paragraph = document.createParagraph();

  FileOutputStream out = new FileOutputStream("create_table.docx"); 
  document.write(out);
  out.close();
  document.close();
 }
}

如果Word-to-PDF转换器不读取该值,则它不完整.当然,您可以停止使用该字段,并将计算出的总和直接放入表格单元格中.但是,由于没有字段了,因此无法使用 Word 更新总和.

If the Word-to-PDF converter don't read the value, then it is incomplete. Of course you could stop using the field and put the calculated sum directly into the table cell. But then updating the sum using Word is not possible since there is not a field anymore.

这篇关于Apache POI或docx4j中的SUM(ABOVE)功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆