質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.45%

  • C#

    9281questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • iOS

    4796questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • Xamarin

    640questions

    Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Xamarin.iOSでブラウザでシェアしたxlsxファイルから、csv形式の文字列を生成したいが文字化けする

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 3
  • VIEW 441

researcher

score 72

現在、Xamarin.iOSでアプリケーションの作成を学んでいる者です

https://www.city.tome.miyagi.jp/kikakuseisaku/documents/042129_aed.xlsx
1.上記xlsx「AED設置箇所一覧」を開いて共有ボタンを押し、自分のアプリケーションを開く
2.そうして取得したxlsxファイルのデータからcsv形式の文字列を生成

以上のような流れを想定してアプリケーションを作成しております。
しかし、上記xlsxファイルの全データを連結して文字列を作成し、Console.WriteLine()で中身を確認したところ、文字化けが起きてしまい困っています

その理由に心当たりのある方がおられましたら、ご教授をお願いします

問題のソースコード

using System;
using System.IO;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Foundation;
using UIKit;
using Cell = DocumentFormat.OpenXml.Spreadsheet.Cell;

namespace TestApp.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
            return base.FinishedLaunching(app, options);
        }

        public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
        {
            if (url.Scheme != "file") { return false; }

            // ファイルを一時保存した場所の特定
            var fileName = url.AbsoluteString.Split('/').Last();
            var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Inbox", fileName);

            if (fileName.EndsWith(".xlsx", StringComparison.CurrentCulture))
            {
                // 編集offで開く
                using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, false))
                {
                    // 開いたブックの各シートのデータをcsv形式の文字列として保存
                    var sheets = document.WorkbookPart.Workbook.Sheets;
                    string[] allCSV = new string[sheets.Count()];
                    int index = 0;
                    foreach (Sheet sheet in sheets)
                    {
                        WorkbookPart wbPart = document.WorkbookPart;
                        var sheetName = sheet.Name;
                        Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName);

                        WorksheetPart wsPart = (WorksheetPart)(wbPart.GetPartById(theSheet.Id));

                        // シートからセルデータを取得してcsvとして保存
                        String[] abc =
                            { "", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
                        StringBuilder csv = new StringBuilder();
                        for (int row = 1, csvEnd = 0; csvEnd == 0; row++)
                        {
                            var csvRow = "";
                            for (int col10 = 0, rowEnd = 0; col10 < 27 && rowEnd == 0; col10++)
                            {
                                for (int col1 = 1; col1 <= 26; col1++)
                                {
                                    Cell theCell = wsPart.Worksheet.Descendants<Cell>().FirstOrDefault(c => c.CellReference == abc[col10] + abc[col1] + row);
                                    // 入力範囲を超えている場合、セルは存在しない。次の行へ移る
                                    if (theCell == null)
                                    {
                                        csvRow = csvRow.TrimEnd(',');
                                        csvRow += Environment.NewLine;
                                        rowEnd = 1;
                                        if (abc[col10] + abc[col1] == "A") { csvEnd = 1; }
                                        break;
                                    }

                                    // 欠損値またはセルの値を記録
                                    var val = theCell.InnerText;
                                    if (string.IsNullOrEmpty(val))
                                    {
                                        csvRow += " ,";
                                    }
                                    else
                                    {
                                        bool canConvert = int.TryParse(val, out int valInt);
                                        if (canConvert)
                                        {
                                            var value = wbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault()
                                                .SharedStringTable.ElementAt(valInt).InnerText;
                                            csvRow += value + ",";
                                        }
                                    }
                                }
                            }

                            Console.WriteLine("少しずつ確認");
                            Console.WriteLine(csv);
                            csv.Append(csvRow);
                        }

                        allCSV[index] = csv.ToString();

                        Console.WriteLine("全行確認");
                        Console.WriteLine(allCSV[index]);

                        index++;
                    }
                }
                return true;
            }
            return false;
        }
    }
}

試したこと

●上記のxlsxの1行目のデータだけを取り込んで、string変数に格納
→問題なく表示された。10行目までのデータからなら文字化けしない

●実機(iPad)ではなくエミュレータ(iphoneXR iOS 12.2)で動かす
→文字化けしなかった

コンソール出力

アプリケーション出力から抜粋
CSVの全行を取得した時
イメージ説明
CSVの一行だけを取得した時
イメージ説明

開発環境

Visual Studio for Mac community
バージョン8.0.7

macOS Mojave
バージョン10.14.4

実行環境

iPad
バージョン12.2

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • korosonya

    2019/05/23 19:06

    ちょっと構成違いますが、Xamarin.Forms の iOS 側で試してみたところ文字化けしませんでした。試した環境は次の通りです。

    * Visual Studio for Mac community: 8.0.5
    * macOS Mojave: 10.14.4
    * DocumentFormat.OpenXml: 2.7.2

    DocumentFormat.OpenXml のバージョンは影響ないでしょうか?
    また、提示されてるコードにはダウンロード部分の処理が含まれていないので、そのあたりになにか原因があるのかもしれません (試した際は .xlsx をダウンロードし、プロジェクト内に埋め込んだ状態でローカルファイルを読み込むようにしました)。

    キャンセル

  • researcher

    2019/05/23 19:18

    korosonyaさん
    DocumentFormat.OpenXml のバージョンは2.9.1と表示されていました
    xlsxファイルのダウンロードは、ブラウザで該当URLを開き、それをシェアボタンからダウンロードしています。分かりづらい質問で申し訳ありませんでした

    キャンセル

  • researcher

    2019/05/23 19:39

    質問内容にも記載しましたが、エミュレーターで試したところ、文字化けせずに出力されました。これを手がかりに、原因を探そうと思います

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.45%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C#

    9281questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • iOS

    4796questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • Xamarin

    640questions

    Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

  • トップ
  • C#に関する質問
  • Xamarin.iOSでブラウザでシェアしたxlsxファイルから、csv形式の文字列を生成したいが文字化けする