0

だから私は、Excelデータを解析する(Gemboxを使用して)作成したこのプログラムを持っています。ただし、ダウンロード/抽出したい一部のワークシートに PDF ファイルが埋め込まれていることがあります。これらのオブジェクトを検出してダウンロードする方法を見つけることができませんでした。これがどのように達成されるかについて正しい方向に私を向けることができる人はいますか? Microsoft には Excel ファイルを読み取る Office ドキュメント エクストラクタがあることは知っていますが、Word などの Office ファイルしか検出しません。

私は誰かに私の仕事をしてコードを書くように頼んでいるわけではありません。私はここで迷子になりました。かなり複雑なプロセスのようです。

4

1 に答える 1

1

更新 (2020-03-28)

GemBox.Spreadsheet の新しいバージョンは をサポートしていExcelWorksheet.EmbeddedObjectsます。

したがって、次のものが使用できるようになりました。

var workbook = ExcelFile.Load("input.xlsx");
var worksheet = workbook.Worksheets[0];

var embeddedObjects = worksheet.EmbeddedObjects;

for (int index = 0; index < embeddedObjects.Count; index++)
{
    ExcelEmbeddedObject embeddedObject = embeddedObjects[index];
    if (embeddedObject.ContentType != "application/vnd.openxmlformats-officedocument.oleObject")
        continue;

    byte[] embeddedBytes;
    using (var memoryStream = new MemoryStream())
    {
        embeddedObject.Data.CopyTo(memoryStream);
        embeddedBytes = memoryStream.ToArray();
    }

    string embeddedContent = Encoding.ASCII.GetString(embeddedBytes);
    int pdfHeaderIndex = embeddedContent.IndexOf("%PDF");
    if (pdfHeaderIndex < 0)
        continue;

    byte[] pdfBytes = new byte[embeddedBytes.Length - pdfHeaderIndex];
    Array.Copy(embeddedBytes, pdfHeaderIndex, pdfBytes, 0, pdfBytes.Length);

    File.WriteAllBytes($"embedded-pdf-{index}.pdf", pdfBytes);
}

オリジナル

GemBox.Spreadsheet は現在これをサポートしていませんが、System.IO.PackagingWindowsBase.dll アセンブリの名前空間で要件を達成できます。

次のコード サンプルを試してください。

using System;
using System.IO;
using System.IO.Packaging;
using System.Text;

static class PdfExtractor
{
    public static void ExtractPdf(string packagePath, string destinationDirectory)
    {
        using (var package = Package.Open(packagePath))
        {
            int i = 1;
            foreach (var part in package.GetParts())
                if (part.ContentType == "application/vnd.openxmlformats-officedocument.oleObject")
                {
                    // PDF data is embedded into OLE Object package part.

                    var pdfContent = GetPdfContent(part.GetStream());
                    if (pdfContent != null)
                        File.WriteAllBytes(Path.Combine(destinationDirectory, "EmbeddedPdf" + (i++) + ".pdf"), pdfContent);
                }
        }
    }

    private static byte[] GetPdfContent(Stream stream)
    {
        // Every PDF file/data starts with '%PDF' and ends with '%%EOF'.
        const string pdfStart = "%PDF", pdfEnd = "%%EOF";

        byte[] bytes = ConvertStreamToArray(stream);

        string text = Encoding.ASCII.GetString(bytes);

        int startIndex = text.IndexOf(pdfStart, StringComparison.Ordinal);
        if (startIndex < 0)
            return null;

        int endIndex = text.LastIndexOf(pdfEnd, StringComparison.Ordinal);
        if (endIndex < 0)
            return null;

        var pdfBytes = new byte[endIndex + pdfEnd.Length - startIndex];
        Array.Copy(bytes, startIndex, pdfBytes, 0, pdfBytes.Length);

        return pdfBytes;
    }

    private static byte[] ConvertStreamToArray(Stream stream)
    {
        var buffer = new byte[16 * 1024];
        using (var ms = new MemoryStream())
        {
            int read;
            while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                ms.Write(buffer, 0, read);

            return ms.ToArray();
        }
    }
}
于 2014-03-17T10:43:25.623 に答える