teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

解決方法の変更

2016/09/07 07:59

投稿

twck
twck

スコア314

answer CHANGED
@@ -6,21 +6,23 @@
6
6
  ```
7
7
  質問文に出てきたこの部分はワークブックではなくワークシートの出力を行っているようです。つまり Template.xlsxファイルの中の一部分しか出力されない。じゃあ Workbook.Saveならどうだとやってみましたが、今度はワークブックの基本情報だけ出力されて、ワークシートが出力されない。しばらく調べてみたのですが、どうにも全体をMemoryStreamに書き出す方法が見つからない。
8
8
 
9
- 開いたファイルを書き換えるのは普通にできるので、ファイルの代わりにBufferedStreamから開いてみたらどうだろうとやってみたら出来ました。ソースがVBなのは申し訳ないですが。
9
+ 開いたファイルを書き換えるのは普通にできるので、ファイルの代わりにMemoryStreamから開いてみたらどうだろうとやってみたら出来ました。
10
- ```VB.NET
10
+ ```C#
11
+ // テンプレートファイルのパス
11
- Dim filename = Server.MapPath("~/App_Data/Template.xlsx")
12
+ var filename = Server.MapPath("~/App_Data/Template.xlsx");
12
- Dim inStream = New System.IO.FileStream(filename, FileMode.Open)
13
- Dim ioStream = New BufferedStream(inStream)
14
13
 
14
+ // ファイルをMemoryStreamに読み込み
15
+ var bytes = System.IO.File.ReadAllBytes(filename);
16
+ using (MemoryStream ms = new MemoryStream(bytes))
17
+ {
18
+ // MemoryStream上のExcelドキュメントを開く
15
- Using document As SpreadsheetDocument = SpreadsheetDocument.Open(ioStream, True)
19
+ using (SpreadsheetDocument document = SpreadsheetDocument.Open(ms, true))
20
+ {
16
- 'この中で編集する
21
+ // 編集する
17
- End Using
22
+ }
18
23
 
19
- Dim size = CType(ioStream.Length, Integer)
24
+ return File(ms.ToArray(), "application/ms-excel", "ダウンロード時のファイル名.xlsx");
20
- Dim bytes(size) As Byte
21
- ioStream.Position = 0
25
+ }
22
- ioStream.Read(bytes, 0, size)
23
- Dim outStream = New MemoryStream(bytes)
24
26
  ```
25
27
 
26
- これなら Template.xlsx を読み込んで、編集して、MemoryStreamに書き出して、送信する、ということができそうですがどうでしょうか?
28
+ これなら Template.xlsx を読み込んで、編集して、送信する、ということができそうですがどうでしょうか?

1

解決策が見つかったので

2016/09/07 07:59

投稿

twck
twck

スコア314

answer CHANGED
@@ -6,19 +6,21 @@
6
6
  ```
7
7
  質問文に出てきたこの部分はワークブックではなくワークシートの出力を行っているようです。つまり Template.xlsxファイルの中の一部分しか出力されない。じゃあ Workbook.Saveならどうだとやってみましたが、今度はワークブックの基本情報だけ出力されて、ワークシートが出力されない。しばらく調べてみたのですが、どうにも全体をMemoryStreamに書き出す方法が見つからない。
8
8
 
9
- 開いたファイルを書き換えるのは普通にできるので、MemoryStreamから開いてみたらどうだろうとやってみました。
9
+ 開いたファイルを書き換えるのは普通にできるので、ファイルの代わりにBufferedStreamから開いてみたらどうだろうとやってみたら出来ました。ソースがVBなのは申し訳ないですが。
10
- ```C#
10
+ ```VB.NET
11
- String fn = Server.MapPath("~/App_Data/Template.xlsx");
11
+ Dim filename = Server.MapPath("~/App_Data/Template.xlsx")
12
- MemoryStream ms = new MemoryStream(System.IO.File.ReadAllBytes(fn), True);
12
+ Dim inStream = New System.IO.FileStream(filename, FileMode.Open)
13
- SpreadsheetDocument document = SpreadsheetDocument.Open(ms, true)
13
+ Dim ioStream = New BufferedStream(inStream)
14
- ```
15
- 読み込むのはうまくいきましたが、documentを閉じる時点で「MemoryStreamには書き込みできない」と例外が発生したのでこの方法もダメ。
16
14
 
15
+ Using document As SpreadsheetDocument = SpreadsheetDocument.Open(ioStream, True)
17
- というわけで今のとろ以下手順しか思いつきません。
16
+ 'この中で編集する
18
- 0. Template.xlsx を一時ファイルとしてコピーする。
19
- 1. 一時ファイルを Open XML SDK で開いて、編集して、保存する。
20
- 2. 保存した一時ファイルを ASP.NET で送信する。
17
+ End Using
21
18
 
22
- 質問者さんはこの質問の後に [ダウンロードさせた完了した後に一時ファイルを削除したい](https://teratail.com/questions/46821) という質問を上げているので、おそらく同じように一時ファイルを使う手段を考え付いたのだと思いますが・・・
19
+ Dim size = CType(ioStream.Length, Integer)
20
+ Dim bytes(size) As Byte
21
+ ioStream.Position = 0
22
+ ioStream.Read(bytes, 0, size)
23
+ Dim outStream = New MemoryStream(bytes)
24
+ ```
23
25
 
24
- で、解決できなかった分際で何が言いたいかというと「Open XML SDK は習得するのに時間が掛かるので、NPOI や ClosedXML や EPPlus にしませんか?」というと。私は NPOI を使用していますが、これなら Template.xlsx を読み込んで、編集して、MemoryStreamに書き出して、送信する、ということができ。よろければぜひ。
26
+ これなら Template.xlsx を読み込んで、編集して、MemoryStreamに書き出して、送信する、ということができそうでがどうでょうか?