Java ApachePOI—编辑Word文件中的图表数据时,它返回到表单中定义的数据

Java ApachePOI—编辑Word文件中的图表数据时,它返回到表单中定义的数据,java,charts,ms-word,apache-poi,docx,Java,Charts,Ms Word,Apache Poi,Docx,我开发了一个包含图表的Word函数。 在Word文件中编辑图表数据时,它将返回到表单中定义的数据 以下是步骤: 我编辑word(docx)xml数据和工作簿 我打开microsoft office-显示的数据正常 单击图表数据编辑功能-返回原始数据 库-ooxml-schemas-1.3,poi-4.0.0-SNAPSHOT public static void main(String[] args) throws Exception { // TODO Auto-generated

我开发了一个包含图表的Word函数。 在Word文件中编辑图表数据时,它将返回到表单中定义的数据

以下是步骤:

  • 我编辑word(docx)xml数据和工作簿
  • 我打开microsoft office-显示的数据正常
  • 单击图表数据编辑功能-返回原始数据
库-ooxml-schemas-1.3,poi-4.0.0-SNAPSHOT

public static void main(String[] args) throws Exception {
    // TODO Auto-generated method stub

    String inFilePath = "../file/temp/TEMP_Chart_Simple.docx";
    String outFilePath = "../file/out/NEW_Chart_" + System.currentTimeMillis() + ".docx";

    Map<String, Map<String, String>> CHART_MAP_DATA = new LinkedHashMap<>();
    Map<String, String> inData = new LinkedHashMap<>();
    inData.put("1", "8.3");
    inData.put("2", "7.3");

    CHART_MAP_DATA.put("temp", inData);

    Path path = Paths.get(inFilePath);
    byte[] byteData = Files.readAllBytes(path);

    // read as XWPFDocument from byte[]
    XWPFDocument document = new XWPFDocument(new ByteArrayInputStream(byteData));

    XWPFChart xChart = null;
    CTChart ctChart = null;
    XSSFWorkbook wb = null;

    for (POIXMLDocumentPart part : document.getRelations()) {
        if (part instanceof XWPFChart) {
            xChart = (XWPFChart) part;
            wb = xChart.getWorkbook();
            ctChart = xChart.getCTChart();

            if(getTitle(ctChart).equals("FIELD_CHART")) {
                break;
            }
        }
    }

    CTPlotArea plotArea = ctChart.getPlotArea();

    List<CTBarChart> arBarChart = plotArea.getBarChartList();
    List<CTBarSer> arBarSer = arBarChart.get(0).getSerList();

    if(CHART_MAP_DATA != null && !CHART_MAP_DATA.isEmpty()) {
        Set<String> keys = CHART_MAP_DATA.keySet();
        Iterator<String> itKeys = keys.iterator();

        while(itKeys.hasNext()) {
            String inKey = itKeys.next();
            Map<String, String> barData = CHART_MAP_DATA.get(inKey);
            setBarChartData(ctChart, serCnt, inKey, barData);
        }
    }

    XSSFSheet sheet = wb.getSheetAt(0);
    sheet.getRow(1).getCell(1).setCellValue(8.3);
    sheet.getRow(2).getCell(1).setCellValue(7.3);

    FileOutputStream fos = new FileOutputStream(new File(outFilePath));
    document.write(fos);

    fos.close();
    document.close();
}

public static void setBarChartData(CTChart ctChart, int serIdx, String series, Map<String, String> data) {
    CTPlotArea plotArea = ctChart.getPlotArea();

    List<CTBarChart> arBarChart = plotArea.getBarChartList();

    if(arBarChart.size() > 0) {
        List<CTBarSer> arBarSer = arBarChart.get(0).getSerList();
        CTBarSer barSer = arBarSer.get(serIdx);    
        CTSerTx serTx = barSer.getTx();
        CTStrRef strRef = serTx.getStrRef();
        CTStrData strData = strRef.getStrCache();
        List<CTStrVal> arStrVal = strData.getPtList();
        for(int b=0; b<arStrVal.size(); b++) {
            arStrVal.get(b).setV(series);
        }

        CTAxDataSource dataSource = barSer.getCat();
        CTStrRef dStrRef = dataSource.getStrRef();

        boolean isCatDataTypeStr = true;
        List<CTStrVal> arDStrVal = null;
        List<CTNumVal> arDNumVal = null;
        CTStrData dStrData = null;
        CTNumData dNumData = null;

        if(dStrRef != null) {
            dStrData = dStrRef.getStrCache();
            arDStrVal = dStrData.getPtList();

            dStrData.getPtCount().setVal(data.size());
            if(arDStrVal.size() > data.size()) {
                for(int i=arDStrVal.size(); i>data.size(); i--) {
                    dStrData.removePt(i-1);
                }
            }

            isCatDataTypeStr = true;
        } else {
            CTNumRef dNumRef = dataSource.getNumRef();
            dNumData = dNumRef.getNumCache();
            arDNumVal = dNumData.getPtList();

            dNumData.getPtCount().setVal(data.size());
            if(arDNumVal.size() > data.size()) {
                for(int i=arDNumVal.size(); i>data.size(); i--) {
                    dNumData.removePt(i-1);
                }
            }

            isCatDataTypeStr = false;
        }

        CTNumDataSource numDataSource = barSer.getVal();
        CTNumRef numRef = numDataSource.getNumRef();
        CTNumData numData = numRef.getNumCache();
        List<CTNumVal> arNumVal = numData.getPtList();

        numData.getPtCount().setVal(data.size());
        if(arNumVal.size() > data.size()) {
            for(int i=arNumVal.size(); i>data.size(); i--) {
                numData.removePt(i-1);
            }
        }

        Set<String> keys = data.keySet();
        Iterator<String> itKeys = keys.iterator();

        int valSize = 0;
        if(isCatDataTypeStr) {
            valSize = arDStrVal.size();
        } else {
            valSize = arDNumVal.size();
        }

        int idx = 0;
        while(itKeys.hasNext()) {
            String stKey = itKeys.next();

            if(valSize > idx) {
                if(isCatDataTypeStr) {
                    arDStrVal.get(idx).setV(stKey);
                } else {
                    arDNumVal.get(idx).setV(stKey);
                }
            } else {
                if(isCatDataTypeStr) {
                    CTStrVal val = dStrData.addNewPt();
                    val.setIdx(idx);
                    val.setV(stKey);
                } else {
                    CTNumVal val = dNumData.addNewPt();
                    val.setIdx(idx);
                    val.setV(stKey);
                }
            }

            if(arNumVal.size() > idx) {
                arNumVal.get(idx).setV(data.get(stKey));
            } else {
                CTNumVal val = numData.addNewPt();
                val.setIdx(idx);
                val.setV(data.get(stKey));
            }

            idx++;
        }
    }
}

public static String getTitle(CTChart chart) {
    CTTitle title = chart.getTitle();
    if (title != null) {
        CTTx tx = title.getTx();
        CTTextBody tb = tx.getRich();

        return tb.getPArray(0).getRArray(0).getT();
    }

    return "";
}
publicstaticvoidmain(字符串[]args)引发异常{
//TODO自动生成的方法存根
字符串inFilePath=“../file/temp/temp\u Chart\u Simple.docx”;
字符串outFilePath=“../file/out/NEW_Chart_quot+System.currentTimeMillis()+”.docx”;
地图图表\地图\数据=新建LinkedHashMap();
Map inData=new LinkedHashMap();
inData.put(“1”、“8.3”);
inData.put(“2”、“7.3”);
图表、地图和数据输入(“临时”,inData);
路径路径=路径。获取(inFilePath);
byte[]byteData=Files.readAllBytes(路径);
//从字节[]读取为XWPFDocument
XWPFDocument document=新的XWPFDocument(新的ByteArrayInputStream(byteData));
XWPFChart xChart=null;
CTChart CTChart=null;
xssfwb=null;
对于(POIXMLDocumentPart:document.getRelations()){
if(XWPFChart的零件实例){
xChart=(XWPFChart)部分;
wb=xChart.get工作簿();
ctChart=xChart.getCTChart();
if(getTitle(ctChart).equals(“FIELD_CHART”)){
打破
}
}
}
CTPlotArea plotArea=ctChart.getPlotArea();
List arBarChart=plotArea.getBarChartList();
List arBarSer=arBarChart.get(0.getSerList();
if(CHART\u MAP\u DATA!=null&!CHART\u MAP\u DATA.isEmpty()){
Set keys=CHART\u MAP\u DATA.keySet();
迭代器itKeys=keys.Iterator();
while(itKeys.hasNext()){
字符串inKey=itKeys.next();
Map barData=图表\地图\数据.get(inKey);
SetBaChartData(ctChart、serCnt、inKey、barData);
}
}
XSSFSheet-sheet=wb.getSheetAt(0);
表.getRow(1.getCell(1.setCellValue)(8.3);
表.getRow(2).getCell(1).setCellValue(7.3);
FileOutputStream fos=新FileOutputStream(新文件(outFilePath));
文件编写(fos);
fos.close();
document.close();
}
公共静态数据(CTChart CTChart、int serIdx、字符串系列、地图数据){
CTPlotArea plotArea=ctChart.getPlotArea();
List arBarChart=plotArea.getBarChartList();
如果(arBarChart.size()>0){
List arBarSer=arBarChart.get(0.getSerList();
CTBarSer=arBarSer.get(serIdx);
CTSerTx=barSer.getTx();
CTStrRef strRef=serTx.getstref();
CTStrData strData=strRef.getStrCache();
List arStrVal=strData.getPtList();
对于(int b=0;b data.size()){
对于(int i=arDStrVal.size();i>data.size();i--){
数据删除(i-1);
}
}
isCatDataTypeStr=true;
}否则{
CTNumRef dNumRef=dataSource.getNumRef();
dNumData=dNumRef.getNumCache();
arDNumVal=dNumData.getPtList();
dNumData.getPtCount().setVal(data.size());
if(arDNumVal.size()>data.size()){
对于(int i=arDNumVal.size();i>data.size();i--){
dNumData.removePt(i-1);
}
}
isCatDataTypeStr=false;
}
CTNumDataSource numDataSource=barSer.getVal();
CTNumRef numRef=numDataSource.getNumRef();
CTNumData numData=numRef.getNumCache();
List arNumVal=numData.getPtList();
numData.getPtCount().setVal(data.size());
if(arNumVal.size()>data.size()){
对于(int i=arNumVal.size();i>data.size();i--){
移除的数值(i-1);
}
}
Set keys=data.keySet();
迭代器itKeys=keys.Iterator();
int-valSize=0;
if(isCatDataTypeStr){
valSize=arDStrVal.size();
}否则{
valSize=arDNumVal.size();
}
int-idx=0;
while(itKeys.hasNext()){
字符串stKey=itKeys.next();
如果(valSize>idx){
if(isCatDataTypeStr){
arDStrVal.get(idx.setV)(stKey);
}否则{
arDNumVal.get(idx.setV)(stKey);
}
}否则{
if(isCatDataTypeStr){
CTStrVal val=dStrData.addNewPt();
val.setIdx(idx);
val.setV(stKey);
}否则{
CTNumVal val=dNumData.addNewPt();
val.setIdx(idx);
val.setV(stKey);
}
}
如果(arNumVal.size()>idx){
arNumVal.get(idx).setV(data.get(stKey));
}否则{
CTNumVal val=numData.addNewPt();
val.setIdx(idx);
val.setV(data.get(stKey));
}
idx++;
}
}
}
公共静态字符串getTitle(CTChart){
CTTitle=chart.getTitle();
如果(标题!=null){
CTTx=title.getTx();
cttextb=tx.getRich();
返回tb.getPArray(0.getRArray(0.getT();
}
返回“”;
}

使用apache poi 4.0.1更改数据需要并行更新基础图表数据工作簿和图表本身中的所有更改。图表保存缓存数据,而工作簿保存源数据。但是这两种方法都可以使用高级的ApachePOI类。不需要访问底层XML bean

范例

Word模板,其模板图表包含2个系列和3个类别:

代码:

import java.io.FileInputStream;
导入java.io.FileOutputStream;
感应电动机
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.CellRangeAddress;

public class WordChangeChartData {

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

  String filePath = "TEMP_Chart_SimpleBar.docx"; // has template chart having 2 series, 3 categories
  String filePathNew = "New_Chart_Simple.docx";

  Object[][] data = new Object[][] { // 2 series, 3 categories
   {"", "male", "female"}, // series titles
   {"health", 123d, 234d}, // category 1
   {"amount", 345d, 123d}, // category 2
   {"size", 180d, 160d} // category 3
  };

  XWPFDocument document = new XWPFDocument(new FileInputStream(filePath));

  XWPFChart chart = document.getCharts().get(0);
  XSSFWorkbook chartDataWorkbook = chart.getWorkbook();
  String sheetName = chartDataWorkbook.getSheetName(0);
  XSSFSheet chartDataSheet = chartDataWorkbook.getSheet(sheetName);

  if (chart.getChartSeries().size() == 1) { // only one chart data
   XDDFChartData chartData = chart.getChartSeries().get(0);
   if (chartData.getSeries().size() == 2) { // exact two series

    int rMin = 1;
    int rMax = 3;

    // set new category data (both series)
    XDDFCategoryDataSource category = null;
    int c = 0;
    for (int r = rMin; r < rMax+1; r++) {
     chartDataSheet.getRow(r).getCell(c).setCellValue((String)data[r][c]); // in sheet
    }
    category = XDDFDataSourcesFactory.fromStringCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); // in chart

    // series 1
    XDDFChartData.Series series1 = chartData.getSeries().get(0);
    c = 1;
    // set new title
    String series1Title = (String)data[0][c];
    chartDataSheet.getRow(0).getCell(c).setCellValue(series1Title); // in sheet
    if (chartDataSheet.getTables().size() > 0) {
     if (chartDataSheet.getTables().get(0).getCTTable().getTableColumns().getTableColumnList().size() > c)
      chartDataSheet.getTables().get(0).getCTTable().getTableColumns().getTableColumnList().get(c).setName(series1Title);
    }
    series1.setTitle(series1Title, new CellReference(sheetName, 0, c, true, true)); // in chart

    // set new values
    XDDFNumericalDataSource<Double> values = null;
    for (int r = rMin; r < rMax+1; r++) {
     chartDataSheet.getRow(r).getCell(c).setCellValue((Double)data[r][c]); // in sheet
    }
    values = XDDFDataSourcesFactory.fromNumericCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); 
    series1.replaceData(category, values);
    series1.plot(); //in chart

    // series 2
    XDDFChartData.Series series2 = chartData.getSeries().get(1);
    c = 2;
    // set new title
    String series2Title = (String)data[0][c];
    chartDataSheet.getRow(0).getCell(c).setCellValue(series2Title); // in sheet
    if (chartDataSheet.getTables().size() > 0) {
     if (chartDataSheet.getTables().get(0).getCTTable().getTableColumns().getTableColumnList().size() > c)
      chartDataSheet.getTables().get(0).getCTTable().getTableColumns().getTableColumnList().get(c).setName(series2Title);
    }
    series2.setTitle(series2Title, new CellReference(sheetName, 0, c, true, true)); // in chart

    // set new values
    for (int r = rMin; r < rMax+1; r++) {
     chartDataSheet.getRow(r).getCell(c).setCellValue((Double)data[r][c]); // in sheet
    }
    values = XDDFDataSourcesFactory.fromNumericCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); 
    series2.replaceData(category, values);
    series2.plot(); // in chart

   }
  }

  FileOutputStream out = new FileOutputStream(filePathNew); 
  document.write(out);
  out.close();
  document.close();
 }

}