使用Java将Ms Word表格的单元格转换为图像

8

我需要将MS Word表格中的每个单元格转换为图像。

我已经编写了getImagegetText的代码,但我想将它们合并并转换为单个图像,因此我只想将单元格转换为图像。

参考

XWPFDocument doc = new XWPFDocument(new FileInputStream(fileName));
        List<XWPFTable> table = doc.getTables();
        for (XWPFTable xwpfTable : table) {
            List<XWPFTableRow> row = xwpfTable.getRows();
            for (XWPFTableRow xwpfTableRow : row) {
                List<XWPFTableCell> cell = xwpfTableRow.getTableCells();
                for (XWPFTableCell xwpfTableCell : cell) {
                    if (xwpfTableCell != null) {
                        System.out.println(xwpfTableCell.getText());
                        String s = xwpfTableCell.getText();
                        for (XWPFParagraph p : xwpfTableCell.getParagraphs()) {
                            for (XWPFRun run : p.getRuns()) {
                                for (XWPFPicture pic : run.getEmbeddedPictures()) {
                                    byte[] pictureData = pic.getPictureData().getData();
                                    System.out.println("picture : " + pictureData);
                                }
                            }
                        }
                    }
                }
            }
        }

那么真正的问题是如何合并文本和图像,对吧?或者是 Apache POI 有什么问题吗? - tak3shi
是的,我想合并文本、图片、剪贴画、流程图等,将它们转换为单个图像单元... 实际上,我不知道如何将单元格或表行转换为图像...! - KuldeeP ChoudharY
如何在图片中添加文本:https://dev59.com/AGgu5IYBdhLWcg3w_b9V - tak3shi
@tak3shi 不,我做不到这一点,因为该单元格还包含以适当格式呈现的形状剪贴画,那我该如何处理呢...! - KuldeeP ChoudharY
POI没有提供将表格转换为图像的功能,您需要自己创建图像并将表格绘制到其中。这里有一个起点:https://dev59.com/T2Mk5IYBdhLWcg3w-Slm - jmarkmurphy
我不认为有这样的支持,但我认为您可以尝试将图像和文本绘制为输出,并截取屏幕截图,因为我没有看到其他方法来解决这个问题。 - Shubham Srivastava
1个回答

3
我找到了解决这个问题的方法,你可以使用Aspose-Word Java库来实现。主要方法如下:
    public static void main(String[] args) throws Exception {
    // The path to the documents directory.
     String dataDir = "D://test//";

    // Load the documents which store the shapes we want to render.
     Document doc = new Document(dataDir + "TestFile.doc");

    // Retrieve the target shape from the document. In our sample document
    // this is the first shape.

    RenderCellToImage(dataDir, doc);
}

//将单元格呈现为图像

public static void RenderCellToImage(String dataDir, Document doc)
        throws Exception {

        Cell cell = (Cell) doc.getChild(NodeType.CELL, 0, true);
        RenderNode(cell, dataDir + "TestFile.RenderCell".png",
                null);
        System.out.println("Cell rendered to image__successfully.");

    }
}
    // / <summary>
// / Renders any node in a document to the path specified using the image
// save options.
// / </summary>
// / <param name="node">The node to render.</param>
// / <param name="path">The path to save the rendered image to.</param>
// / <param name="imageOptions">The image options to use during rendering.
// This can be null.</param>
public static void RenderNode(Node node, String filePath,
        ImageSaveOptions imageOptions) throws Exception {
    // Run some argument checks.
    if (node == null)
        throw new IllegalArgumentException("Node cannot be null");

    // If no image options are supplied, create default options.
    if (imageOptions == null)
        imageOptions = new ImageSaveOptions(FileFormatUtil.extensionToSaveFormat((filePath.split("\\.")[filePath
                        .split("\\.").length - 1])));

    // Store the paper color to be used on the final image and change to
    // transparent.
    // This will cause any content around the rendered node to be removed
    // later on.
    Color savePaperColor = imageOptions.getPaperColor();
    // imageOptions.PaperColor = Color.Transparent;
    imageOptions.setPaperColor(new Color(0, 0, 0, 0));
    // There a bug which affects the cache of a cloned node. To avoid this
    // we instead clone the entire document including all nodes,
    // find the matching node in the cloned document and render that
    // instead.
    Document doc = (Document) node.getDocument().deepClone(true);
    node = doc.getChild(NodeType.ANY,node.getDocument().getChildNodes(NodeType.ANY, true).indexOf(node), true);

    // Create a temporary shape to store the target node in. This shape will
    // be rendered to retrieve
    // the rendered content of the node.
    Shape shape = new Shape(doc, ShapeType.TEXT_BOX);

    Section parentSection = (Section) node.getAncestor(NodeType.SECTION);

    // Assume that the node cannot be larger than the page in size.
    shape.setWidth(parentSection.getPageSetup().getPageWidth());
    shape.setHeight(parentSection.getPageSetup().getPageHeight());
    shape.setFillColor(new Color(0, 0, 0, 0)); // We must make the shape and
                                                // paper color transparent.

    // Don't draw a surrounding line on the shape.
    shape.setStroked(false);

    // Move up through the DOM until we find node which is suitable to
    // insert into a Shape (a node with a parent can contain paragraph,
    // tables the same as a shape).
    // Each parent node is cloned on the way up so even a descendant node
    // passed to this method can be rendered.
    // Since we are working with the actual nodes of the document we need to
    // clone the target node into the temporary shape.
    Node currentNode = node;
    while (!(currentNode.getParentNode() instanceof InlineStory
            || currentNode.getParentNode() instanceof Story || currentNode
                .getParentNode() instanceof ShapeBase)) {
        CompositeNode parent = (CompositeNode) currentNode.getParentNode()
                .deepClone(false);
        currentNode = currentNode.getParentNode();
        parent.appendChild(node.deepClone(true));
        node = parent; // Store this new node to be inserted into the shape.
    }

    // We must add the shape to the document tree to have it rendered.
    shape.appendChild(node.deepClone(true));
    parentSection.getBody().getFirstParagraph().appendChild(shape);

    // Render the shape to stream so we can take advantage of the effects of
    // the ImageSaveOptions class.
    // Retrieve the rendered image and remove the shape from the document.
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    shape.getShapeRenderer().save(stream, imageOptions);
    shape.remove();

    // Load the image into a new bitmap.
    BufferedImage renderedImage = ImageIO.read(new ByteArrayInputStream(
            stream.toByteArray()));

    // Extract the actual content of the image by cropping transparent space
    // around
    // the rendered shape.
    Rectangle cropRectangle = FindBoundingBoxAroundNode(renderedImage);

    BufferedImage croppedImage = new BufferedImage(cropRectangle.width,
            cropRectangle.height, BufferedImage.TYPE_INT_RGB);

    // Create the final image with the proper background color.
    Graphics2D g = croppedImage.createGraphics();
    g.setBackground(savePaperColor);
    g.clearRect(0, 0, croppedImage.getWidth(), croppedImage.getHeight());

    g.drawImage(renderedImage, 0, 0, croppedImage.getWidth(),
            croppedImage.getHeight(), cropRectangle.x, cropRectangle.y,
            cropRectangle.x + cropRectangle.width, cropRectangle.y
                    + cropRectangle.height, null);




    ImageIO.write(croppedImage, "png", new File(filePath));
}

这个很好用,但是单元格中的文本字体在图像中没有被保留。有什么想法为什么会这样? - amankapur91

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接