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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

iOS

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

Xamarin

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

Q&A

0回答

485閲覧

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

researcher

総合スコア87

C#

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

iOS

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

Xamarin

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

0グッド

3クリップ

投稿2019/05/23 04:31

編集2019/05/23 10:38

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

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

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

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

問題のソースコード

AppDelegate

1using System; 2using System.IO; 3using System.Linq; 4using System.Text; 5using DocumentFormat.OpenXml.Packaging; 6using DocumentFormat.OpenXml.Spreadsheet; 7using Foundation; 8using UIKit; 9using Cell = DocumentFormat.OpenXml.Spreadsheet.Cell; 10 11namespace TestApp.iOS 12{ 13 [Register("AppDelegate")] 14 public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 15 { 16 public override bool FinishedLaunching(UIApplication app, NSDictionary options) 17 { 18 global::Xamarin.Forms.Forms.Init(); 19 LoadApplication(new App()); 20 return base.FinishedLaunching(app, options); 21 } 22 23 public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options) 24 { 25 if (url.Scheme != "file") { return false; } 26 27 // ファイルを一時保存した場所の特定 28 var fileName = url.AbsoluteString.Split('/').Last(); 29 var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Inbox", fileName); 30 31 if (fileName.EndsWith(".xlsx", StringComparison.CurrentCulture)) 32 { 33 // 編集offで開く 34 using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, false)) 35 { 36 // 開いたブックの各シートのデータをcsv形式の文字列として保存 37 var sheets = document.WorkbookPart.Workbook.Sheets; 38 string[] allCSV = new string[sheets.Count()]; 39 int index = 0; 40 foreach (Sheet sheet in sheets) 41 { 42 WorkbookPart wbPart = document.WorkbookPart; 43 var sheetName = sheet.Name; 44 Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName); 45 46 WorksheetPart wsPart = (WorksheetPart)(wbPart.GetPartById(theSheet.Id)); 47 48 // シートからセルデータを取得してcsvとして保存 49 String[] abc = 50 { "", "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" }; 51 StringBuilder csv = new StringBuilder(); 52 for (int row = 1, csvEnd = 0; csvEnd == 0; row++) 53 { 54 var csvRow = ""; 55 for (int col10 = 0, rowEnd = 0; col10 < 27 && rowEnd == 0; col10++) 56 { 57 for (int col1 = 1; col1 <= 26; col1++) 58 { 59 Cell theCell = wsPart.Worksheet.Descendants<Cell>().FirstOrDefault(c => c.CellReference == abc[col10] + abc[col1] + row); 60 // 入力範囲を超えている場合、セルは存在しない。次の行へ移る 61 if (theCell == null) 62 { 63 csvRow = csvRow.TrimEnd(','); 64 csvRow += Environment.NewLine; 65 rowEnd = 1; 66 if (abc[col10] + abc[col1] == "A") { csvEnd = 1; } 67 break; 68 } 69 70 // 欠損値またはセルの値を記録 71 var val = theCell.InnerText; 72 if (string.IsNullOrEmpty(val)) 73 { 74 csvRow += " ,"; 75 } 76 else 77 { 78 bool canConvert = int.TryParse(val, out int valInt); 79 if (canConvert) 80 { 81 var value = wbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault() 82 .SharedStringTable.ElementAt(valInt).InnerText; 83 csvRow += value + ","; 84 } 85 } 86 } 87 } 88 89 Console.WriteLine("少しずつ確認"); 90 Console.WriteLine(csv); 91 csv.Append(csvRow); 92 } 93 94 allCSV[index] = csv.ToString(); 95 96 Console.WriteLine("全行確認"); 97 Console.WriteLine(allCSV[index]); 98 99 index++; 100 } 101 } 102 return true; 103 } 104 return false; 105 } 106 } 107}

試したこと

●上記の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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/05/23 04:40

Xamarin で Console ってどういうことですか?
ozwk

2019/05/23 04:41

"該当コード"にConsole.WriteLineが無いですけど?
researcher

2019/05/23 04:42

Console.WriteLine(data)のような感じで中身を確認しようとしたのですが、 すみません、そこからして誤っているのでしょうか?
researcher

2019/05/23 04:44

>>ozwkさん すみません、修正します
Zuishin

2019/05/23 04:45

つまり、Console.WriteLine を使った時だけ化けるということですか? どこにリダイレクトされてます?
researcher

2019/05/23 04:48

Console.WriteLine以外で中身を見ていないので、その時だけ化けるかどうかを調査していませんでした。 自分の知識と理解が足りず恐縮ですが、リダイレクトとはどういう意味でしょう?
Zuishin

2019/05/23 04:50

つまり、アプリを実機で動かしたわけではなく、Visual Studio の出力ウィンドウが文字化けしているということですか? 開発環境の OS と IDE の、それぞれの名称とバージョンを書いてください。
m.ts10806

2019/05/23 04:51

どういう文字列を投入したのでしょうか。 同じような構成の50とか100字程度の文字列では確認されましたか?
Zuishin

2019/05/23 04:58

Console.WriteLine は標準出力に文字列を出力するので、リダイレクトという作業で出力先が変わります。要するに、文字列がどこに出力されているかということを聞いたわけですが、ファイルやターミナルではなく IDE の出力ウィンドウということでいいんですよね?
researcher

2019/05/23 05:03 編集

>>Zuisinさん Visual Studioの出力ウィンドウで文字化けしている、の通りです。アプリケーション出力のウィンドウを見ております 開発環境の情報を質問文に加えます。もし他に足りない情報があれば、お手数ですがご指摘をお願いします >>mts10806さん 文字列はCSVなのですが、1行目だけ(100字程度)を文字列に格納した時は問題なく表示されるような状況です
m.ts10806

2019/05/23 05:08

2行目以降を出したときは全て文字化けしているということでしょうか。 それとも1行目は文字化けせずに2行目以降だけ文字化けしていますか? 「試したこと」として状況を質問本文に追記してください。
researcher

2019/05/23 05:11

>>mts10806 失礼しました。少々お待ちください
Zuishin

2019/05/23 05:16

ひょっとして、CSV が途中から化けてるんじゃないですか?
m.ts10806

2019/05/23 05:20

文字化け確認ができる程度でいいのでサンプルデータ欲しいですね
researcher

2019/05/23 05:22

元々のcsvデータが文字化けをしている、という解釈でよろしいでしょうか? https://www.city.tome.miyagi.jp/kikakuseisaku/documents/042129_aed.xlsx 上記のオープンデータからCSVを取り込んでいるのですが、確認したところ、元のデータに文字化けはないように思われます。 念の為、CSVを取り込んだ際に何かの原因で化けてしまっていないか確認をしてきます。
m.ts10806

2019/05/23 05:25

取り込む処理を書いているコードも追記願います。
researcher

2019/05/23 05:27

承知いたしました。 質問文の改訂を行います
Zuishin

2019/05/23 06:08

コンパイルエラーになりますよ。違うソースじゃないですか?
Zuishin

2019/05/23 06:09

エラーを修正すると文字化け無く表示されました。
researcher

2019/05/23 06:12

エラーになりますか? 一応動作確認をしてからコピペを行ったのですが、 申し訳ないのですが、どこで何のエラーが出たのか教えてもらえないでしょうか?
Zuishin

2019/05/23 06:14

エラーは複数ありますが、軽微なものなので問題ではありません。違うソースということが問題です。
researcher

2019/05/23 06:19

ソースコードを確認しましたが、質問文に記載したもので、私が動かしているコードに間違いありませんでした。 私の環境で動かしますと、Console.WriteLine(data);の出力がやはり文字化けしてしまいます。 こちらの環境に問題があるということなのでしょうか?
Zuishin

2019/05/23 06:22

いえ、明らかな文法エラーなので、このソースではありません。
researcher

2019/05/23 06:23

承知しました。再度よく確認いたします
m.ts10806

2019/05/23 06:26

Xamarinよくわからないですがコンソール出力時にSystem.ってつけなくても出るんですか?
researcher

2019/05/23 06:29 編集

すみません、コードを名前空間の指定含む全文載せなかったのが過ちでした using System ;で名前空間の指定をしています。 それを含めて、コードの修正をいたします
m.ts10806

2019/05/23 06:33

ああなるほど。了解です。 回答者的には「コピペすれば現象再現できる」ことを期待するので省略してるのであれば一言入れてもらえると混乱がないです
Zuishin

2019/05/23 06:35

そこではありません。
Zuishin

2019/05/23 06:37

名前空間やクラスの省略ならば「違うソース」とは言いません。明らかに文法的に間違っていて、コンパイルできないところがあります。 そして、そこを直せと言っているのではありません。 ソースが違うので、これを元にデバッグすることはできません。
researcher

2019/05/23 06:58

質問文のコードを修正いたしました。動作確認をし、文字化けする箇所であることも確認しています。 ご迷惑をおかけしますが、よろしくお願いいたします
Zuishin

2019/05/23 07:01

変わってないですね。いっそ、今のプロジェクトとは別に新しいプロジェクトを作り、この掲載されたソースをそのままコピペしてください。それをもとに話しましょう。 ここに掲載されたソース以外は使い回さず、全て新規で作り直してください。おそらくその中に問題が含まれています。 掲載されたソースも、手元のものではなく、必ずこの質問からコピペしてください。
researcher

2019/05/23 07:03

承知いたしました。ご指示頂いた通りに修正いたします
researcher

2019/05/23 07:22

1.新規プロジェクトを作成 2.この質問文のコードをAppDelegate.csにコピペ 3.info.plistのドキュメントの種類をpublic.dataで登録 4.NugetのDocumentFormat.OpenXmlを追加 を行ったのですが、Console.WriteLine(data)の出力がやはり文字化けしております。 必要最低限のことだけを行ったつもりですが、何か余計な手順が含まれましたでしょうか?
m.ts10806

2019/05/23 07:25

実行結果の画面、提示いただけますか?
Zuishin

2019/05/23 07:28

文字化けの対策はまだしてなくて、それ以前にちゃんと意図したソースがコンパイルされているかどうかを確かめています。 これがコンパイルできたとなると、私の手には負えそうにありません。もう一度調べてみますが、あまり期待できないと思ってください。
researcher

2019/05/23 07:33

>>mts10806さん 実行結果の画面をスクショしました。 >>Zuishinさん ここまで熱心にお付き合い頂けただけで、非常に心強いです。お気遣い痛み入ります
m.ts10806

2019/05/23 07:56

関係ないかもしれませんが、原本のExcelからCSVってどうやって作ってます? また、CSV自体の文字コードはどうなってますか? 1件だけのものと全件のもの、それぞれ確認して結果を追記いただければと思います。
researcher

2019/05/23 08:06

ExcelからCSVを作成する方法ですが、ダウンロードしたexcelファイルのセルを列方向に一つずつ参照し、そこから1行分のcsv文字列を生成、さらに一行ずつリストに格納することで生成しております。
Zuishin

2019/05/23 08:08

ちょっと待ってください。このコードでは CSV は扱えません。やはり何かおかしいです。
researcher

2019/05/23 08:11

すみません、詳しく説明をお願いしてもいいでしょうか?
m.ts10806

2019/05/23 08:13 編集

ん???かなり遠回りの手順のように思いますが、 ファイル開いて「名前を付けて保存」→「ファイルの種類:CSV」で作ったCSVではどうですか?
researcher

2019/05/23 08:25

officeが入っていないので、エクセルをgoogleスプレッドシートとして保存して、それをcsvとして保存したところから開いてみたところ、同じく文字化けして出力されました。 文字コードが原因なのでしょうか?
m.ts10806

2019/05/23 08:27

文字化けが出たといえば最初に文字コードを疑うのは定石ではありますので、「もしかしたら」と思いまして。 ※ごめんなさい。Macでしたね。Windows Office前提の手順をコメントしてしまいました。
tamoto

2019/05/23 08:30

ちょっと質問なんですが、、外部のCSVデータ……CSVデータを読み込み……とか何度も言ってましたけど、質問のコードが .xlsx のエクセルファイルを開いて読むものなのはどういう意味なんでしょうか?全然違うコードを貼っていませんか?
Zuishin

2019/05/23 08:32

おかしいのがまず、このコードはコンパイルできるはずがない、つまり実行できないはずのものであるということです。 次に、このコードは CSV ファイルではなく、全くフォーマットの違う XLSX 形式のファイルを読むものだということです。 中でやっている処理にしても意味不明ですが、これはまた次の話で、それ以前に、絶対に動くはずがない物が動いていることがおかしいということです。 違うものを起動しているんじゃないでしょうか?
researcher

2019/05/23 08:36

>>Zuishinさん tamotoさん 私の質問の記載不備です。申し訳ありません。質問にあげたコードは、.xlsxとして保存されているデータをcsvとして取得することを意図している、で伝わりますでしょうか? 一応、新規プロジェクトを作って試してみたので、確認したいコードを見れているとは思います。実機に入れたアプリのアイコンも違うものです
YAmaGNZ

2019/05/23 08:39 編集

CSVって言っているから話が合わないのかと 前のコメントでこのデータとあげているのがxlsxファイルで、これをプログラム内でカンマ区切りにしているだけで、CSVファイルを読み込んでいるわけではないですよね。 質問者さんがxlsxファイルとCSVファイルの区別がついていないのかと
researcher

2019/05/23 08:44 編集

>>YAmaGNZさん おっしゃる通りです! それが本来言いたかったことでした。 私の日本語能力の不足のせいです。本当にご迷惑をおかけいたします。 ダウンロードして読み込んでいるのはxlsxファイルであって、CSVファイルではないです。 それを内部でカンマ区切りにして文字列として保存しようとしています。 そしてその保存した文字列を出力すると、文字数によって文字化けしてしまう、という流れです。 すみません、これで伝わりますでしょうか?
Zuishin

2019/05/23 08:45

私はこれを XLSX から CSV を作り、それを再度分解して、更に CSV に戻す処理をしていると認識して、その辺りを忖度して読んでいたんですが、そうすると CSV ファイルを与えた場合、例外が発生するはずです。 となれば文字化けではなく、処理が中断するので、CSV ファイルを与えてなお文字化けが起こるはずがありません。
m.ts10806

2019/05/23 08:46

CSV「ファイル」として保存して .csvを読み込むためのコードにすればいけそうな気がしないでもないですね。.xlsxそのまま読んでるからデータがおかしくなっているようにも思います。
Zuishin

2019/05/23 08:47

ですから、名前を付けて保存で作った CSV の話で、やはりおかしいと思いました。
researcher

2019/05/23 08:54

すみません、指摘を頂いた中でようやく穴だらけの質問をしてしまったと気づいたので、ソースコードと質問内容を修正します
Zuishin

2019/05/23 08:58

一つ思い当たるのが、与えられたファイル名を加工していることで、これで文字化けや CSV を与えても例外が生じないことについては説明をつけることができます。つまりドロップしたファイルとは違う別のファイルを開いているということですね。 しかし、そもそもコンパイルできないはずなので、そこの説明がどうしてもつきません。
tamoto

2019/05/23 08:59

ところでところで、本題からさらにズレズレですいませんなんですが、追記依頼にデータソースとして載せてたxlsxの配布場所を見にいったら、 https://www.city.tome.miyagi.jp/kikakuseisaku/opendata.html 普通に CSV がそのまま置いてあるんですよねえ。xlsx の方中見てないのでアレなんですが、これ、そのまま欲しいものだったりしないんです?案の定sjisなのが行政ゥ~って感じですが……
PineMatsu

2019/05/23 09:00

大量の文字列追加なら、StringBuilderを使ったらどうですか?
researcher

2019/05/23 09:07

<<tamotoさん データが欲しいならわざわざxlsxの方を入れる必要ないのは仰る通りです。そうなのですがすみません、ここまで色々な方のお世話になっておきながら恐縮なのですが、そもそもがxlsx引っ張ってきて加工できないのかな、という興味からの学習が目的でして、できればxlsxファイルを入れる方向で達成したいと思っています。 <<PineMatsuさん ご指摘の通りですね。すっかり失念しておりました。まずはそこを直したいと思います
tamoto

2019/05/23 09:10

なるほど理解しました。学習目的なら全然ありです。ちゃんと実現できるはずなので、がんばって解決しましょう。
korosonya

2019/05/23 10: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 10:18

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

2019/05/23 10:39

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問