java - 通过 TIKA 将 word 文档转换为带有嵌入图像的 HTML

标签 java c# apache-tika

我是 TIKA 的新人。我尝试使用 Tika 将 Microsoft word 文档转换为 HTML。我正在使用 TikaOnDotNet 包装器在 .Net 框架上使用 TIKA。我的转换代码如下:

        byte[] file = Files.toByteArray(new File(@"myPath\document.doc"));
        AutoDetectParser tikaParser = new AutoDetectParser();

        ByteArrayOutputStream output = new ByteArrayOutputStream();
        SAXTransformerFactory factory = (SAXTransformerFactory)TransformerFactory.newInstance();
        TransformerHandler handler = factory.newTransformerHandler();
        handler.getTransformer().setOutputProperty(OutputKeys.METHOD, "html");
        handler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");
        handler.getTransformer().setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        handler.setResult(new StreamResult(output));

        ExpandedTitleContentHandler handler1 = new ExpandedTitleContentHandler(handler);

        tikaParser.parse(new ByteArrayInputStream(file), handler1, new Metadata());


        File ofile = new File(@"C:\toHtml\text.html");
        ofile.createNewFile();
        DataOutputStream stream = new DataOutputStream(new FileOutputStream(ofile));
        output.writeTo(stream);

除了嵌入图像外,一切正常。生成的 HTML 包含图像标签,例如:

<img src="embedded:image2.wmf" alt="image2.wmf"/>

但图片来源不存在。请多多指教

最佳答案

鸣谢@Gagravarr。

请注意,这是一个简单的代码实现,原始代码可在问题的评论中找到。

此实现基于 TikaOnDotNet 包装器.....

public class DocToHtml
{

    private TikaConfig config = TikaConfig.getDefaultConfig();
    public void Convert()
    {

        byte[] file = Files.toByteArray(new File(@"filename.doc"));
        AutoDetectParser tikaParser = new AutoDetectParser();

        ByteArrayOutputStream output = new ByteArrayOutputStream();
        SAXTransformerFactory factory = (SAXTransformerFactory)TransformerFactory.newInstance();
        var inputStream = new ByteArrayInputStream(file);
        //           ToHTMLContentHandler handler = new ToHTMLContentHandler();
        var metaData = new Metadata();
        EncodingDetector encodingDetector = new UniversalEncodingDetector();
        var encode = encodingDetector.detect(inputStream, metaData) ?? new UTF_32();
        TransformerHandler handler = factory.newTransformerHandler();
        handler.getTransformer().setOutputProperty(OutputKeys.METHOD, "html");
        handler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");
        handler.getTransformer().setOutputProperty(OutputKeys.ENCODING, encode.toString());
        handler.setResult(new StreamResult(output));

        ContentHandler imageRewriting = new ImageRewritingContentHandler(handler); 

        //  ExpandedTitleContentHandler handler1 = new ExpandedTitleContentHandler(handler);
        ParseContext context = new ParseContext();
        context.set(typeof(EmbeddedDocumentExtractor), new FileEmbeddedDocumentEtractor());

        tikaParser.parse(inputStream, imageRewriting, new Metadata(), context);


        byte[] array =  output.toByteArray();

       System.IO.File.WriteAllBytes(@"C:\toHtml\text.html", array);

    }


    private class ImageRewritingContentHandler : ContentHandlerDecorator
    {
        public ImageRewritingContentHandler(ContentHandler handler) : base(handler)
        {
        }

        public override void startElement(string uri, string localName, string name, Attributes origAttrs)
        {
            if ("img".Equals(localName))
            {
                AttributesImpl attrs;
                if (origAttrs is AttributesImpl)
                    attrs = (AttributesImpl)origAttrs;
                else
                    attrs = new AttributesImpl(origAttrs);



                for (int i = 0; i < attrs.getLength(); i++)
                {
                    if ("src".Equals(attrs.getLocalName(i)))
                    {
                        String src = attrs.getValue(i);
                        if (src.StartsWith("embedded:"))
                        {
                            var newSrc = src.Replace("embedded:", @"images\");

                            attrs.setValue(i, newSrc);
                        }
                    }
                }
                attrs.addAttribute(null, "width", "width","width", "100px");
                base.startElement(uri, localName, name, attrs);
            }
            else
                base.startElement(uri, localName, name, origAttrs);
        }
    }

    private class FileEmbeddedDocumentEtractor : EmbeddedDocumentExtractor
    {
        private int count = 0;
        public bool shouldParseEmbedded(Metadata m)
        {
            return true;
        }

        public void parseEmbedded(InputStream inputStream, ContentHandler contentHandler, Metadata metadata, bool outputHtml)
        {
            Detector detector = new DefaultDetector();
            string name = metadata.get("resourceName");
            MediaType contentType = detector.detect(inputStream, metadata);
            if (contentType.getType() != "image") return;
            var embeddedFile = name;
            File outputFile = new File(@"C:\toHtml\images", embeddedFile);
            try
            {
                using (FileOutputStream os = new FileOutputStream(outputFile))
                {
                    var tin = inputStream as TikaInputStream;
                    if (tin != null)
                    {
                        if (tin.getOpenContainer() != null && tin.getOpenContainer() is DirectoryEntry)
                        {
                            POIFSFileSystem fs = new POIFSFileSystem();

                            fs.writeFilesystem(os);
                        }
                        else
                        {
                            IOUtils.copy(inputStream, os);
                        }
                    }
                }
            }
            catch (Exception ex)
            {

                throw;
            }
        }
    }
}

关于java - 通过 TIKA 将 word 文档转换为带有嵌入图像的 HTML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38577468/

相关文章:

java - jList 在一行中输出所有内容

java - 批量读取 Couchbase 文档

java - 如何防止 Mockito 动态地 mock ......?

c# - AES 加密文件中是否有 Salt 和 IV 的标准位置

java - 如何为几种文档类型正确配置 Apache Tika?

Java Math.sin() 无法按预期工作

c# - 文本分类从文本中提取标签

c# - Linq 通过 List<T> (System.Collection.Generic.List) 对象过滤 IQueryable<T> (System.Data.Linq.DataQuery) 对象?

java - Tika 1.14 : getting java. PDFTextStripper 的 lang.NullPointerException

python - 属性错误 : 'bytes' object has no attribute 'close' when Tika parser is run