I have a Web API used to save some generated PDFs.
I use the following code:
[HttpPut]
[Route("getfile")]
public HttpResponseMessage GenerateFile(RequestView requestView)
{
var result = new HttpResponseMessage(HttpStatusCode.OK);
using (var stream = new FileStream(#"C:\sample.pdf", FileMode.Open) { Position = 0 })
{
result.Content = new StreamContent(stream);
MemoryStream ms = new MemoryStream();
stream.CopyTo(ms);
result.Content = new ByteArrayContent(ms.ToArray());
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = "Sample.pdf" };
result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
result.Content.Headers.ContentDisposition.FileName = "Sample.pdf";
result.Content.Headers.ContentLength = stream.Length;
}
return result;
}
But what i get is:
The response looks like:
%PDF-1.3
%âãÏÓ
1 0 obj
<<
/Type /Catalog
/Outlines 2 0 R
/Pages 3 0 R
>>
endobj
2 0 obj
<<
/Type /Outlines
/Count 0
>>
endobj
.
.
.
And the headers:
Does anyone have any clues related to this?
Thanks.
Set response content to ByteArrayContent instead of StreamContent, Also make sure to add .pdf extention to result.Content.Headers.ContentDisposition.FileName = "Sample.pdf";
[HttpPut]
[Route("getfile")]
public HttpResponseMessage GenerateFile(RequestView requestView)
{
var result = new HttpResponseMessage(HttpStatusCode.OK);
using (var stream = new FileStream(#"C:\sample.pdf", FileMode.Open) { Position = 0 })
{
result.Content = new StreamContent(stream);
MemoryStream ms = new MemoryStream();
stream.CopyTo(ms);
result.Content = new ByteArrayContent(ms.ToArray());
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = "Sample.pdf" };
result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
result.Content.Headers.ContentDisposition.FileName = "Sample.pdf";
result.Content.Headers.ContentLength = stream.Length;
}
return result;
}
Couple of things I notice: one is that you're setting the content length. This shouldn't be required and I'd remove it.
Secondly, you don't provide FileStream constructor parameters for things like FileAccess. I'd replace that with this, which should achieve what you need:
var stream = File.OpenRead(#"D:\sample.pdf");
Related
I am generating a PDF from HTML and I had some file which was added in PDF in this format:
BUT those link unable to download - I get an "Unauthorized" error...
My code:
if (DocumentAfter != null)
{
string documentAElement = "";
foreach (var item in DocumentAfter)
{
var path2 = FromEmaillID + item.FileName;
// var filePath2 = Path.Combine(Environment.WebRootPath, #"document", item.FileName);
documentAElement += "" + item.FileName + "<br />";
}
emailKeyValues.Add(EmailConstants.AfterDocuments, documentAElement);
}
In this code there are more than one file I am adding in an anchor tag and it will then assign to html with EmailConstants.AfterDocuments
And my pdf download code is
Byte[] bytes;
StringBuilder sb1 = new StringBuilder();
sb1.Append(emailMessage.Content);//Pass html string here
StringReader sr = new StringReader(sb1.ToString());
Document pdfDoc = new Document(PageSize.A4, 25, 25, 25, 25);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
using (MemoryStream memoryStream = new MemoryStream())
{
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, memoryStream);
pdfDoc.Open();
XMLWorkerHelper.GetInstance().ParseXHtml(writer, pdfDoc, sr);
//htmlparser.Parse(sr);
pdfDoc.Close();
bytes = memoryStream.ToArray();
memoryStream.Close();
//var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "yogTest.pdf");
System.IO.File.WriteAllBytes(filepath1, bytes);
}
This code is working properly as PDF is shown, but only the file which I am adding for downloading is not working?
I am trying to convert a PDF page to an image, to create thumbnails. This is the code that I am using:
PdfRenderer pdfRenderer = new PdfRenderer(GetSeekableFileDescriptor(filePath));
var appDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
string directoryPath = System.IO.Path.Combine(appDirectory, "thumbnailsTemp", System.IO.Path.GetFileNameWithoutExtension(fileName));
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
int pageCount = pdfRenderer.PageCount;
for (int i = 0; i < pageCount; i++)
{
Page page = pdfRenderer.OpenPage(i);
Android.Graphics.Bitmap bmp = Android.Graphics.Bitmap.CreateBitmap(page.Width, page.Height, Android.Graphics.Bitmap.Config.Rgb565 or Argb8888);
page.Render(bmp, null, null, PdfRenderMode.ForDisplay);
try
{
using (FileStream output = new FileStream(System.IO.Path.Combine(directoryPath, fileName + "Thumbnails" + i + ".png"), FileMode.Create))
{
bmp.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 100, output);
}
page.Close();
}
catch (Exception ex)
{
//TODO -- GERER CETTE EXPEXPTION
throw new Exception();
}
}
return directoryPath;
}
I tried with ARGB 8888 and that was a success. But the rendering time was too slow for big PDF files. This is why I tried to improve it by changing the format to RGB 565. But my app is crashing with this Execption:
Unsuported pixel format
Any idea to fix this, or how to render a PDF to a bitmap faster? I was looking on google but didn't find a solution related to my code.
UPDATE
I did this but know, my app is crashing at this line of code :
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
My class :
public async Task<string> GetBitmaps(string filePath)
{
//TODO -- WORK ON THIS
PdfRenderer pdfRenderer = new PdfRenderer(GetSeekableFileDescriptor(filePath));
var appDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
string directoryPath = System.IO.Path.Combine(appDirectory, "thumbnailsTemp", System.IO.Path.GetFileNameWithoutExtension(fileName));
var stream = new MemoryStream();
using (Stream resourceStream = new FileStream(filePath, FileMode.Open))
{
resourceStream.CopyTo(stream);
}
for (int i = 0; i < pdfRenderer.PageCount; i++)
{
TallComponents.PDF.Rasterizer.Page page = new TallComponents.PDF.Rasterizer.Page(stream, i);
byte[] bytes = null;
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
using (FileStream output = new FileStream(System.IO.Path.Combine(directoryPath, fileName + "Thumbnails" + i + ".png"), FileMode.Create, FileAccess.Write))
{
output.Write(bytes, 0, bytes.Length);
}
}
return directoryPath;
}
you could draw a PDF page in app by converting a PDF page to a bitmap,here the PDF document itself is embedded as a resource.
var assembly = Assembly.GetExecutingAssembly();
var stream = new MemoryStream();
using (Stream resourceStream = assembly.GetManifestResourceStream("DrawPdf.Android.tiger.pdf"))
{
resourceStream.CopyTo(stream);
}
Page page = new Page(stream, 0);
// render PDF Page object to a Bitmap
byte[] bytes = null;
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
Bitmap bmp = global::Android.Graphics.BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length);
I have this code to upload a rar file to server and this works. But when i download the file from server, contents of file are spoiled. Please tell me how can I fix that. Thanks.
public ActionResult UpFile(HttpPostedFileBase upFile)
{
string fileName = System.IO.Path.GetFileName(upFile.FileName);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://myhostaddress.com/" + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("myUserName", "MyPassword");
StreamReader streamReader = new StreamReader(upFile.InputStream);
byte[] fileContents = Encoding.Default.GetBytes(streamReader.ReadToEnd());
streamReader.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
return RedirectToAction("/");
}
This code is working for me, try it:
var request = (FtpWebRequest)WebRequest.Create(ftp + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(user, pass);
using (var input = File.OpenRead(filePth))
{
using (var output = request.GetRequestStream())
{
input.CopyTo(output);
}
}
var response = (FtpWebResponse)request.GetResponse();
response.Close();
IArchive archive = null;
IReader reader = null;
archive = SevenZipArchive.Open(fileStream, Options.LookForHeader);
reader = archive.ExtractAllEntries();
while (reader.MoveToNextEntry())
{
if (!reader.Entry.IsDirectory)
{
Stream _redaer = new MemoryStream();
reader.WriteEntryTo(_redaer);
fileName = reader.Entry.FilePath;
int index = fileName.LastIndexOf("/");
string file = fileName.Substring(index + 1, (fileName.Length - (index + 1)));
using (binaryReader = new BinaryReader(_redaer, encoding))
{
long fileLength = _redaer.Length;
MemoryStream ms = new MemoryStream();
_redaer.Position = 0;
_redaer.CopyTo(ms);
byte[] buteArray = ms.ToArray();
SaveToIsoStore(fileName, buteArray);
}
}
}
This code gives exception of type SharpCompress.Common.InvalidFormatException,Please provide the solution in wp7.
I've verified using System.Text.Encoding.ASCII.GetString(ms.ToArray)); that my memorystream has the expected data.
However using the LinqToCSV nuget library will not generate my csv file. I get no errors or exceptions thrown. I just get an empty file when I'm prompted to open the file.
Here is my Action Method
public FileStreamResult Export(){
var results = _service.GetProperties().Take(3);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.TextWriter txt = new System.IO.StreamWriter(ms);
CsvFileDescription inputFileDescription = new CsvFileDescription{
SeparatorChar =',',
FirstLineHasColumnNames = true
}
;
CsvContext csv = new CsvContext();
csv.Write(results,txt,inputFileDescription);
return File(ms , "application/x-excel");
}
I find it interesting, if I change the return type to contentResult, and the return method to Content() and pass it System.Text.Encoding.ASCII.GetString(ms.ToArray)); I do get a browser window showing my data.
Make sure you reset stream position to 0. Also make sure you flush your StreamWriter before that.
Calling the Web API method to return CVS file from JavaScript.
public HttpResponseMessage Bidreport([FromBody]int formData).....
Fill in your IEnumerable<YourObject>query = from LINQ query
....
This is how to return it:
using (var ms = new MemoryStream())
{
using (TextWriter txt = new StreamWriter(ms))
{
var cc = new CsvContext();
cc.Write(query, txt, outputFileDescription);
txt.Flush();
ms.Position = 0;
var fileData = Encoding.ASCII.GetString(ms.ToArray());
var result = new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent(fileData)};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-excel");
return result;
}
}