我有一个工作簿,里面有一些数据。我正在使用该工作簿并根据另一个工作簿中的数据创建另一个工作簿,其中包含一个折线图。代码运行良好,但每当我打开图形文件时,我都会收到警告 We can't update some of the links in your workbook right now。如果我单击警告菜单中的 Edit Links... 按钮,它会显示找不到数据工作簿。如果我单击 Change Source...,然后选择适当的工作簿,它就可以正常工作。为什么是这样? POI可以不保留两个文件之间的链接吗?
我的代码:
创建数据工作簿:
public static XSSFWorkbook createDataSpreadsheet(String name, long[] data) {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(name);
int rowNumber = 0;
for(int i = 1; i < data.length + 1; i++) {
Row row = sheet.createRow(rowNumber++);
int columnNumber = 0;
row.createCell(columnNumber++).setCellValue(i);
row.createCell(columnNumber++).setCellValue(data[i - 1]);
}
return workbook;
}
创建图形工作簿:
public static XSSFWorkbook createLineChart(String name, XSSFWorkbook data) {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(name);
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 15, 15);
XSSFChart lineChart = drawing.createChart(anchor);
XSSFChartLegend 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);
XSSFSheet 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 });
return workbook;
}
最佳答案
在 XSSF 中创建外部链接直到现在还没有很好地实现。有 ExternalLinksTable但如果你看看 Uses of this Class然后你会看到只提供读取那些外部链接,但不提供创建和写入。
所以我们需要使用低级对象。我们需要了解 Office OpenXML *.xlsx ZIP 存档中此外部链接的内部依赖关系。
只要两个工作簿都存储在同一目录中,以下内容就可以工作。
代码主要是您提供的代码,添加了用于创建指向另一个工作簿中工作表的外部链接的方法。这种方法使用的是底层对象,不是很通用,但应该能说明原理。
您的代码的其他更改也有注释。
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 添加到 XSSFWorkbook 中的 ExternalLinksTable 列表中。因此,在进一步使用该工作簿时将可以获得它。
该方法只需要链接工作簿和链接工作表的名称。它自己管理 ID。它返回 ExternalLinksTable 的 Id(作为 /xl/externalLinks/externalLink1.xml 中的 1。所以这个 Id 可以用作公式中的外部工作簿引用(作为1 在 [1]ChartDataSheet!$A$1:$A$20).
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;
}
}
}
由于图表创建方面的变化,上述 2017 年的代码示例将无法使用当前的 apache poi 版本。但是使用 ExternalLinksTable 创建链接到具有图表数据的外部工作簿的图表的问题仍然存在。因此,我将提供可用于当前 apache poi 版本 4.x.y 和 5.0.0 的代码示例。它现在使用新的 XDDF 内容来创建图表。
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.model.ExternalLinksTable;
import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.openxml4j.opc.*;
//import org.apache.poi.POIXMLDocumentPart; // up to apache poi 3.17
import org.apache.poi.ooxml.POIXMLDocumentPart; // since apache poi 4.0.0
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; // up to apache poi 3.17
import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; // since apache poi 4.0.0
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, "./"+datawbname);
Workbook chartwb = createLineChart("ChartSheet", (XSSFWorkbook)datawb);
saveWorkbook(chartwb, "./"+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 {
XSSFWorkbook workbook = new MyXSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(name);
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 15, 15);
XSSFChart lineChart = drawing.createChart(anchor);
XDDFChartLegend legend = lineChart.getOrAddLegend();
legend.setPosition(LegendPosition.BOTTOM);
XDDFCategoryAxis bottomAxis = lineChart.createCategoryAxis(AxisPosition.BOTTOM);
XDDFValueAxis leftAxis = lineChart.createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
XSSFSheet dataSheet = data.getSheetAt(0);
XDDFDataSource<Double> xData = XDDFDataSourcesFactory.fromNumericCellRange(dataSheet, new CellRangeAddress(0, dataSheet.getLastRowNum(), 0, 0));
XDDFNumericalDataSource<Double> yData = XDDFDataSourcesFactory.fromNumericCellRange(dataSheet, new CellRangeAddress(0, dataSheet.getLastRowNum(), 1, 1));
XDDFLineChartData chartData = (XDDFLineChartData) lineChart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
XDDFLineChartData.Series series = (XDDFLineChartData.Series) chartData.addSeries(xData, yData);
series.setTitle("A Title", null);
lineChart.plot(chartData);
//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;
}
}
}
关于java - 为什么我不能在 Apache POI 中将一个工作簿链接到另一个工作簿?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46508297/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返