निर्माण अच्छी तरह से अब तक लागू नहीं किया गया। ExternalLinksTable है लेकिन यदि आप Uses of this Class पर देखते हैं तो आप देखेंगे कि केवल उन बाहरी लिंक को पढ़ा गया है लेकिन बनाना और लिखना नहीं है।
इसलिए हमें निम्न स्तर की वस्तुओं के साथ काम करने की आवश्यकता है। और हमें Office OpenXML *.xlsx
ज़िप-संग्रह के भीतर इस बाहरी लिंक की आंतरिक निर्भरताओं के बारे में ज्ञान चाहिए।
निम्न कार्य करता है जब तक कि दोनों कार्यपुस्तिकाएं उसी निर्देशिका में संग्रहीत की जाती हैं।
कोड मुख्य रूप से आपके प्रदान किए गए कोड को अन्य कार्यपुस्तिका में शीट के बाहरी लिंक बनाने के लिए विधि के साथ जोड़ा गया है। यह विधि निम्न स्तर की वस्तुओं का उपयोग कर रही है और यह बहुत सामान्य उपयोग नहीं है, लेकिन इसे सिद्धांत दिखाना चाहिए।
आपके कोड में अन्य परिवर्तन भी टिप्पणी की गई हैं।
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.model.ExternalLinksTable;
import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.POIXMLDocumentPart;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.ExternalLinkDocument;
import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
public class CreateExcelLineChartDataAnotherWorkbook {
private static String datawbname = "DataWB.xlsx";
private static String chartwbname = "ChartWB.xlsx";
public CreateExcelLineChartDataAnotherWorkbook() throws Exception {
Workbook datawb = createDataSpreadsheet("ChartDataSheet");
saveWorkbook(datawb, "/home/axel/Dokumente/"+datawbname);
Workbook chartwb = createLineChart("ChartSheet", (XSSFWorkbook)datawb);
saveWorkbook(chartwb, "/home/axel/Dokumente/"+chartwbname);
}
//your method only partially changed to have sample data
public XSSFWorkbook createDataSpreadsheet(String name) {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet(name);
int rowNumber = 0;
for(int i = 0; i < 20; i++) {
Row row = sheet.createRow(rowNumber++);
int columnNumber = 0;
row.createCell(columnNumber++).setCellValue(Math.PI*i/10*2);
row.createCell(columnNumber++).setCellValue(Math.sin(Math.PI*i/10*2));
}
return (XSSFWorkbook)workbook;
}
//method for saving the workbooks
public void saveWorkbook(Workbook wb, String path) throws Exception {
wb.write(new FileOutputStream(path));
wb.close();
}
//your method changes are commented
public XSSFWorkbook createLineChart(String name, XSSFWorkbook data) throws Exception {
Workbook workbook = new XSSFWorkbook();
//create the external link to datawbname
int extwbid = 1;
createExternalLinkToWorksheet((XSSFWorkbook)workbook, datawbname, "ChartDataSheet", "rId"+extwbid);
Sheet sheet = workbook.createSheet(name);
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 15, 15);
Chart lineChart = drawing.createChart(anchor);
ChartLegend legend = lineChart.getOrCreateLegend();
legend.setPosition(LegendPosition.BOTTOM);
LineChartData chartData = lineChart.getChartDataFactory().createLineChartData();
ChartAxis bottomAxis = lineChart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = lineChart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
Sheet dataSheet = data.getSheetAt(0);
ChartDataSource<Number> xData = DataSources.fromNumericCellRange(dataSheet, new CellRangeAddress(0, dataSheet.getLastRowNum(), 0, 0));
ChartDataSource<Number> yData = DataSources.fromNumericCellRange(dataSheet, new CellRangeAddress(0, dataSheet.getLastRowNum(), 1, 1));
LineChartSeries chartSeries = chartData.addSeries(xData, yData);
chartSeries.setTitle("A title");
lineChart.plot(chartData, new ChartAxis[] { bottomAxis, leftAxis });
//since dataSheet is an external sheet, the formula in the org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef
//must be prefixed with [1], where 1 is the Id of the linked workbook
String catref = ((XSSFChart)lineChart).getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getCat().getNumRef().getF();
((XSSFChart)lineChart).getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getCat().getNumRef().setF("[" + extwbid + "]" + catref);
String valref = ((XSSFChart)lineChart).getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getVal().getNumRef().getF();
((XSSFChart)lineChart).getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getVal().getNumRef().setF("[" + extwbid + "]" + valref);
return (XSSFWorkbook)workbook;
}
//method for creating a external link to a sheet in another workbook
public void createExternalLinkToWorksheet(XSSFWorkbook workbook, String wbname, String sheetname, String rIdExtWb) throws Exception {
OPCPackage opcpackage = workbook.getPackage();
//creating /xl/externalLinks/externalLink1.xml having link to externalBook with external sheetName
PackagePartName partname = PackagingURIHelper.createPartName("/xl/externalLinks/externalLink1.xml");
PackagePart part = opcpackage.createPart(partname, "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml");
POIXMLDocumentPart externallinkstable = new POIXMLDocumentPart(part) {
@Override
protected void commit() throws IOException {
PackagePart part = getPackagePart();
OutputStream out = part.getOutputStream();
try {
ExternalLinkDocument doc = ExternalLinkDocument.Factory.parse(
"<externalLink xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">"
+"<externalBook xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\""+ rIdExtWb + "\">"
+"<sheetNames><sheetName val=\"" + sheetname + "\"/></sheetNames>"
+"</externalBook>"
+"</externalLink>"
);
doc.save(out, DEFAULT_XML_OPTIONS);
out.close();
} catch (Exception ex) {
ex.printStackTrace();
};
}
};
//creating the relation to the external workbook in /xl/externalLinks/_rels/externalLink1.xml.rels
PackageRelationship packrelship = part.addRelationship(new java.net.URI(wbname), TargetMode.EXTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath", rIdExtWb);
//creating the relation to /xl/externalLinks/externalLink1.xml in /xl/_rels/workbook.xml.rels
String rIdExtLink = "rId" + (workbook.getRelationParts().size()+1);
workbook.addRelation(rIdExtLink, XSSFRelation.EXTERNAL_LINKS, externallinkstable);
//creating the <externalReferences><externalReference .../> in /xl/workbook.xml
workbook.getCTWorkbook().addNewExternalReferences().addNewExternalReference().setId(rIdExtLink);
}
public static void main(String[] args) throws Exception {
CreateExcelLineChartDataAnotherWorkbook mainObject = new CreateExcelLineChartDataAnotherWorkbook();
}
}
मेरा नया कोड एक क्लास MyXSSFWorkbook
जो जुड़ा हुआ कार्यपुस्तिका और शीट के लिए ExternalLinksTable
बनाने के लिए विधि द्वारा XSSFWorkbook
फैली प्रदान करता है। यह कोड वास्तव में ExternalLinksTable बनाता है और यह ExternalLinksTable
में ExternalLinksTable
एस की सूची में जोड़ने के लिए प्रतिबिंब का उपयोग करता है। तो यह कार्यपुस्तिका का उपयोग कर आगे मिल जाएगा।
विधि केवल लिंक की गई कार्यपुस्तिका और लिंक्ड शीट के नामों की आवश्यकता है। यह आईडी स्वयं ही प्रबंधित करता है। यह ExternalLinksTable
की आईडी (रिटर्न के रूप में /xl/externalLinks/externalLink1.xml
में 1।, ताकि यह आईडी बाहरी कार्यपुस्तिका संदर्भ के रूप में सूत्रों में ([1]ChartDataSheet!$A$1:$A$20
में 1) के रूप में इस्तेमाल किया जा सकता।
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.model.ExternalLinksTable;
import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.POIXMLDocumentPart;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.ExternalLinkDocument;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTExternalReferences;
import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
import java.lang.reflect.Field;
import java.util.List;
import java.util.ArrayList;
public class CreateExcelLineChartExternalLinksTable {
private static String datawbname = "DataWB.xlsx";
private static String chartwbname = "ChartWB.xlsx";
public CreateExcelLineChartExternalLinksTable() throws Exception {
Workbook datawb = createDataSpreadsheet("ChartDataSheet");
saveWorkbook(datawb, "/home/axel/Dokumente/"+datawbname);
Workbook chartwb = createLineChart("ChartSheet", (XSSFWorkbook)datawb);
saveWorkbook(chartwb, "/home/axel/Dokumente/"+chartwbname);
}
//your method only partially changed to have sample data
public XSSFWorkbook createDataSpreadsheet(String name) {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet(name);
int rowNumber = 0;
for(int i = 0; i < 20; i++) {
Row row = sheet.createRow(rowNumber++);
int columnNumber = 0;
row.createCell(columnNumber++).setCellValue(Math.PI*i/10*2);
row.createCell(columnNumber++).setCellValue(Math.sin(Math.PI*i/10*2));
}
return (XSSFWorkbook)workbook;
}
//method for saving the workbooks
public void saveWorkbook(Workbook wb, String path) throws Exception {
wb.write(new FileOutputStream(path));
wb.close();
}
//your method changes are commented
public XSSFWorkbook createLineChart(String name, XSSFWorkbook data) throws Exception {
Workbook workbook = new MyXSSFWorkbook();
Sheet sheet = workbook.createSheet(name);
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 15, 15);
Chart lineChart = drawing.createChart(anchor);
ChartLegend legend = lineChart.getOrCreateLegend();
legend.setPosition(LegendPosition.BOTTOM);
LineChartData chartData = lineChart.getChartDataFactory().createLineChartData();
ChartAxis bottomAxis = lineChart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
ValueAxis leftAxis = lineChart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
Sheet dataSheet = data.getSheetAt(0);
ChartDataSource<Number> xData = DataSources.fromNumericCellRange(dataSheet, new CellRangeAddress(0, dataSheet.getLastRowNum(), 0, 0));
ChartDataSource<Number> yData = DataSources.fromNumericCellRange(dataSheet, new CellRangeAddress(0, dataSheet.getLastRowNum(), 1, 1));
LineChartSeries chartSeries = chartData.addSeries(xData, yData);
chartSeries.setTitle("A title");
lineChart.plot(chartData, new ChartAxis[] { bottomAxis, leftAxis });
//create the ExternalLinksTable for the linked workbook and sheet
int extLinksId = ((MyXSSFWorkbook)workbook).createExternalLinksTableWbSheet(datawbname, "ChartDataSheet");
System.out.println(((XSSFWorkbook)workbook).getExternalLinksTable());
//since dataSheet is an external sheet, the formula in the org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef
//must be prefixed with [1], where 1 is the Id of the linked workbook
String catref = ((XSSFChart)lineChart).getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getCat().getNumRef().getF();
((XSSFChart)lineChart).getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getCat().getNumRef().setF("["+extLinksId+"]" + catref);
String valref = ((XSSFChart)lineChart).getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getVal().getNumRef().getF();
((XSSFChart)lineChart).getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getVal().getNumRef().setF("["+extLinksId+"]" + valref);
return (XSSFWorkbook)workbook;
}
public static void main(String[] args) throws Exception {
CreateExcelLineChartExternalLinksTable mainObject = new CreateExcelLineChartExternalLinksTable();
}
//class which extends XSSFWorkbook and provides a method for creating ExternalLinksTable for linked workbook and sheet
private class MyXSSFWorkbook extends XSSFWorkbook {
//method for creating ExternalLinksTable for linked workbook and sheet
//returns the Id of this ExternalLinksTable
int createExternalLinksTableWbSheet(String wbname, String sheetname) throws Exception {
List<ExternalLinksTable> elternallinkstablelist = getExternalLinksTable();
int extLinksId = 1;
if (elternallinkstablelist != null) extLinksId = elternallinkstablelist.size()+1;
OPCPackage opcpackage = getPackage();
//creating /xl/externalLinks/externalLink1.xml having link to externalBook with external sheetName
PackagePartName partname = PackagingURIHelper.createPartName("/xl/externalLinks/externalLink"+extLinksId+".xml");
PackagePart part = opcpackage.createPart(partname, "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml");
OutputStream out = part.getOutputStream();
ExternalLinkDocument doc = ExternalLinkDocument.Factory.parse(
"<externalLink xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">"
+"<externalBook xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\"rId1\">"
+"<sheetNames><sheetName val=\"" + sheetname + "\"/></sheetNames>"
+"</externalBook>"
+"</externalLink>"
);
doc.save(out, DEFAULT_XML_OPTIONS);
out.close();
//creating the relation to the external workbook in /xl/externalLinks/_rels/externalLink1.xml.rels
PackageRelationship packrelship = part.addRelationship(new java.net.URI(wbname), TargetMode.EXTERNAL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath", "rId1");
ExternalLinksTable externallinkstable = new ExternalLinksTable(part);
//creating the relation to /xl/externalLinks/externalLink1.xml in /xl/_rels/workbook.xml.rels
String rIdExtLink = "rId" + (getRelationParts().size()+1);
addRelation(rIdExtLink, XSSFRelation.EXTERNAL_LINKS, externallinkstable);
//creating the <externalReferences><externalReference .../> in /xl/workbook.xml
CTExternalReferences externalreferences = getCTWorkbook().getExternalReferences();
if (externalreferences == null) externalreferences = getCTWorkbook().addNewExternalReferences();
externalreferences.addNewExternalReference().setId(rIdExtLink);
Field externalLinksField = XSSFWorkbook.class.getDeclaredField("externalLinks");
externalLinksField.setAccessible(true);
@SuppressWarnings("unchecked") //we know the problem and expect runtime error if it possibly occurs
List<ExternalLinksTable> externalLinks = (ArrayList<ExternalLinksTable>)externalLinksField.get(this);
if (externalLinks == null) {
externalLinks = new ArrayList<ExternalLinksTable>();
externalLinks.add(externallinkstable);
externalLinksField.set(this, externalLinks);
} else {
externalLinks.add(externallinkstable);
}
return extLinksId;
}
}
}
अच्छा जवाब। यह काम करता है, लेकिन मैं इंतज़ार कर रहा हूँ यह देखने के लिए कि क्या कोई ऐसा समाधान पोस्ट करता है जो सरल और अधिक पोर्टेबल/लचीला है। जैसा कि आपने अपने उत्तर में कहा है, यह बहुत कम स्तर है और आमतौर पर प्रयोग योग्य नहीं है। –
@Alex Quilliam: मैंने नया कोड प्रदान किया है जो अधिक सामान्य उपयोग योग्य है। –