添加形状超链接后,无法读取的代码为Excel 2010

时间:2019-01-15 09:45:47

标签: java excel apache-poi

我在Java应用程序中具有Excel报表生成功能。

我终于用以下代码成功地将超链接添加到图片中。

buildHyperLinksMenu 是设置超链接的主要功能

createHyperLinkWithUri 是创建Uri超链接的子函数

public void buildHyperLinksMenu(String linkName, XSSFSheet sheet, String tabLinked, String referencedCell) {
    List<XSSFShape> shapes = sheet.getDrawingPatriarch().getShapes();
    Iterator<XSSFShape> elementsIterator = shapes.iterator();

    while (elementsIterator.hasNext()) {

        XSSFShape shape = elementsIterator.next();
        if (shape instanceof XSSFPicture) {
            CTPicture ctPicture = ((XSSFPicture) shape).getCTPicture();
            CTPictureNonVisual ctpicturenonvisual = ctPicture.getNvPicPr();
            CTNonVisualDrawingProps ctnonvisualdrawingprops = ctpicturenonvisual.getCNvPr();
            String finalname = ctnonvisualdrawingprops.getName();
            //HomeLink is the name of the picture assigned in the sheet to 
            //the image when uploading the Excel template
            if (finalname.equals("HomeLink")) {
                CTHyperlink link = createHyperLinkWithUri(linkName, sheet, tabLinked, referencedCell);
                ((XSSFPicture) shape).getCTPicture().getNvPicPr().getCNvPr().setHlinkClick(link);
            }
        }
    }
}

private CTHyperlink createHyperLinkWithUri(String linkName, XSSFSheet sheet, String tabLinked, String referencedCell) {
    CTHyperlink link = CTHyperlink.Factory.newInstance();
    try {
        String hyperlinkAddress = sheet.getPackagePart().getPartName() + "/#'" + tabLinked + "'!" + referencedCell + "";
        URI uri = new URI(null, null, hyperlinkAddress, null, null);
        sheet.getDrawingPatriarch().getPackagePart().addRelationship(uri, TargetMode.INTERNAL, XSSFRelation.SHEET_HYPERLINKS.getRelation());

        String relationshipId = null;
        PackageRelationshipCollection prc = sheet.getDrawingPatriarch().getPackagePart().getRelationships();
        for (PackageRelationship pr : prc) {
            URI targetURI = pr.getTargetURI();
            String target = targetURI.getPath();
            if (target.equals(hyperlinkAddress)) {
                relationshipId = pr.getId();
                break;
            }
        }

        CTHyperlink hyperlink = CTHyperlink.Factory.newInstance();
        // Set ID of hyperlink to be the same as Relationship ID
        hyperlink.setId(relationshipId);
        return hyperlink;
    } catch (URISyntaxException | InvalidFormatException e) {
        return link;
    }
}

现在的问题是,生成后,excel(打开时)将提示“内容不可读”消息,并且未添加超链接。

我想了解这是我丢失的一段代码的问题还是更令人讨厌的问题,例如库的版本等。

我确认if (finalname.equals("HomeLink"))一次也只有一次满足。

这是一个简单的函数,用于在输出中写入文件:

protected byte[] workbookToByteArray(XSSFWorkbook workbook) {
    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
        workbook.write(byteArrayOutputStream);

        return byteArrayOutputStream.toByteArray();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

谢谢

Davide

UDPATE

我生成了一个带有或不带有添加HyperLink(基本上是上面的代码)功能的Excel文档。

损坏的Excel表示文件xl \ drawings \ drawing4.xml是损坏的文件。 因此,我将这两个优点,解压缩并比较了xml文件。两者之间的唯一区别是:

更正文件

<a:blip xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:embed="rId2">

vs

文件错误

<a:blip r:embed="rId2">

这种差异多次以类似的方式发生。很多别的

UDPATE

似乎是造成问题的那一行是在将关系添加到包中时

    sheet.getDrawingPatriarch().getPackagePart().addRelationship(uri, TargetMode.INTERNAL, XSSFRelation.SHEET_HYPERLINKS.getRelation());

解决方案代码

public void buildHyperLinksMenu(String linkName, XSSFSheet sheet, String tabLinked, String referencedCell) {
    List<XSSFShape> shapes = sheet.getDrawingPatriarch().getShapes();
    Iterator<XSSFShape> elementsIterator = shapes.iterator();

while (elementsIterator.hasNext()) {

    XSSFShape shape = elementsIterator.next();
    if (shape instanceof XSSFPicture) {
        CTPicture ctPicture = ((XSSFPicture) shape).getCTPicture();
        CTPictureNonVisual ctpicturenonvisual = ctPicture.getNvPicPr();
        CTNonVisualDrawingProps ctnonvisualdrawingprops = ctpicturenonvisual.getCNvPr();                 
        String finalname = ctnonvisualdrawingprops.getName();
        if (finalname.equals("HomeLink")) {
            CTHyperlink link = createHyperLinkWithUri(linkName, sheet, tabLinked, referencedCell);
            ((XSSFPicture) shape).getCTPicture().getNvPicPr().getCNvPr().setHlinkClick(link);


        }
    }
}

}

private CTHyperlink createHyperLinkWithUri(String linkName, XSSFSheet sheet, String tabLinked, String referencedCell) {
    CTHyperlink link = CTHyperlink.Factory.newInstance();
    try {
        CTHyperlink hyperlink = CTHyperlink.Factory.newInstance();
        String hyperlinkAddress = "#'" + tabLinked + "'!" + referencedCell + "";
        sheet.getDrawingPatriarch().getPackagePart().addExternalRelationship(hyperlinkAddress, PackageRelationshipTypes.HYPERLINK_PART);

        String relationshipId = null;
        PackageRelationshipCollection prc = sheet.getDrawingPatriarch().getPackagePart().getRelationships();
        for (PackageRelationship pr : prc) {
            String targetURI = pr.getTargetURI().toString();
            if (targetURI.equals(hyperlinkAddress)) {
                relationshipId = pr.getId();
                break;
            }
        }

        // Set ID of hyperlink to be the same as Relationship ID
        hyperlink.setId(relationshipId);
        return hyperlink;
    } catch (InvalidFormatException e) {
        return link;
    }
}

0 个答案:

没有答案