I want to export image which is displayed on web page. This image is stored in Sql image data type. While displaying image I am converting the image to Base64String.
Image1.ImageUrl = "data:image/jpg;base64," & Convert.ToBase64String(imgPhoto)
While exporting page, image is not displaying in word document file.
I can not store image on the server because of security reason.
below code is for export to word file.
Response.AddHeader("content-disposition", "attachment;filename=Test.doc")
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = "application/ms-word "
Response.Charset = ""
Dim stringWrite As New System.IO.StringWriter()
Dim htmlWrite As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite)
' Create a form to contain the grid
ControlID.RenderControl(htmlWrite)
Dim stringWrite1 As New System.IO.StringWriter()
Dim htmlWrite1 As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite1)
' Create a form to contain the grid
ImageLogo.RenderControl(htmlWrite1)
Response.Write(stringWrite1.ToString() & stringWrite.ToString())
Response.[End]()
You really aren't creating a Word document, just rendering the HTML to a word MIME type. I don't believe word supports the data:image definition since that is much newer than the pre-2007 word format. Instead, try the OpenXML SDK. Although it creates Word 2007+ documents only, most people can view them. The OpenXML SDK will enable you to create a real word doc and create an image from the binary image data.
http://www.microsoft.com/en-us/download/details.aspx?id=30425
http://msdn.microsoft.com/en-us/library/office/bb448854%28v=office.15%29.aspx
Related
I briefly summarize my problem:
I'm calling an API that returns a pdf like
"% PDF-1.4%%1 0 obj
<<
/ Type / Catalog/ PageLayout / OneColumn/
Pages 2 0 R/ PageMode / UseNone
......... "
currently, I receive it in string format to be able to make changes and so far so good, but after making changes I would like to convert the string to blob to download the pdf. In doing this I am having problems, the text string converted to blob does not generate the correct pdf, or rather the pdf once opened is white, when in reality it should have data.
The code I'm using now is the following:
response.text().then((content) => {
//...TODO: Modify pdf
var blob = new Blob([content], { type: "application/pdf" });
saveAs(blob, "invoice.pdf");
}).catch(error => {
console.log(error);
});
The pdf is downloaded but if I open it it is empty.
I would like to be able to modify the pdf string and convert it back into a blob to be able to download it.
Does anyone have an idea how I could do it?
A PDF consists of a set of objects in a non-trivial fashion. If you are receiving it as a string and are using standard string manipulation functions on it, e.g. find and replace you are most likely going to corrupt it. You would have to edit in accord with the standards laid out in the PDF specification and not violate the syntax. This is a very fragile approach, you need to use a PDF library instead to edit your PDF content.
I have a problem (or may be two) with saving files using HTML5 File API.
A files comes from the server as a byte array and I need to save it. I tried several ways described on SO:
creating blob and opening it in a new tab
creating a hidden anchor tag with "data:" in href attribute
using FileSaver.js
All approaches allow to save the file but with breaking it by changing the encoding to UTF-8, while the file (in current test case) is in ANSI. And it seems that I have to problems: at the server side and at the client side.
Server side:
Server side is ASP.NET Web API 2 app, which controller sends the file using HttpResponseMessage with StreamContent. The ContentType is correct and corresponds with actual file type.
But as can be seen on the screenshot below server's answer (data.length) is less then actual file size calculated at upload (file.size). Also here could be seen that HTML5 File object has yet another size (f.size).
If I add CharSet with value "ANSI" to server's response message's ContentType property, file data will be the same as it was uploaded, but on saving result file still has wrong size and become broken:
Client side:
I tried to set charset using the JS File options, but it didn't help. As could be found here and here Eli Grey, the author of FileUplaod.js says that
The encoding/charset in the type is just metadata for the browser, not an encoding directive.
which means, if I understood it right, that it is impossible to change the encoding of the file.
Issue result: at the end I can successfully download broken files which are unable to open.
So I have two questions:
How can I save file "as is" using File API. At present time I cannot use simple way with direct link and 'download' attribute because of serverside check for access_token in request header. May be this is the "bottle neck" of the problem?
How can I avoid setting CharSet at server side and also send byte array "as is"? While this problem could be hacked in some way I guess it's more critical. For example, while "ANSI" charset solves the problem with the current file, WinMerge shows that it's encoding is Cyrillic 'Windows-1251' and also can any other.
P.S. the issue is related to all file types (extensions) except *.txt.
Update
Server side code:
public HttpResponseMessage DownloadAttachment(Guid fileId)
{
var stream = GetFileStream(fileId);
var message = new HttpResponseMessage(HttpStatusCode.OK);
message.Content = new StreamContent(stream);
message.Content.Headers.ContentLength = file.Size;
message.Content.Headers.ContentType = new MediaTypeHeaderValue(file.ContentType)
{
// without this charset files sent with bigger size
// than they are as shown on image 1
CharSet = "ANSI"
};
message.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = file.FileName + file.Extension,
Size = file.Size
};
return message;
}
Client side code (TypeScript):
/*
* Handler for click event on download <a> tag
*/
private downloadFile(file: Models.File) {
var self = this;
this.$service.downloadAttachment(this.entityId, file.fileId).then(
// on success
function (data, status, headers, config) {
var fileName = file.fileName + file.extension;
var clientFile = new File([data], fileName);
// here's the issue ---^
saveAs(clientFile, fileName);
},
// on fail
function (error) {
self.alertError(error);
});
}
My code is almost the same as in answers on related questions on SO: instead of setting direct link in 'a' tag, I handle click on it and download file content via XHR (in my case using Angularjs $http service). Getting the file content I create a Blob object (in my case I use File class that derives from Blob) and then try to save it using FileSaver.js. I also tried approach with encoded URL to Blob in href attribute, but it only opens a new tab with a file broken the same way. I found that the problem is in Blob class - calling it's constructor with 'normal' file data I get an instance with 'wrong' size as could be seen on first two screenshots. So, as I understand, my problem not in the way I try to save my file, but in the way I create it - File API
I am building an app that pulls files from SharePoint 2013 or SharePoint 2010 for view in HTML. In C#, files are pulled out of SharePoint (multipage documents like Word, Excel, PDF, TIFF, etc), then are fed into various 3rd party software (DataLogics and Aspose) - which break the documents down into their individual pages, then streams the individual pages to the browser in PNG format.
So in HTML, we have an img element whose src is set to a specific URL in an ASHX service. The ASHX service grabs the file out of SharePoint and, based on query string params, returns the desired page as a Stream.
Here is how we shoot it back:
[WebService(Namespace = "url")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FileTransfer : IHttpHandler, IReadOnlySessionState
{
public void ProcessRequest(HttpContext context)
var stream = GetStream(context.Request);
int chunkSize = 2097152; //2MB
byte[] chunk = new byte[chunkSize];
int bytesRead = 0;
do {
bytesRead = stream.Read(chunk, 0, chunkSize);
HttpContext.Current.Response.OutputStream.Write(chunk, 0, bytesRead);
}
while (bytesRead > 0);
}
This works perfectly 100% of the time in any browser when the file we are breaking down comes directly from SharePoint.
We also provide a feature where the user can upload a document. This is where the problem comes in. Uploaded documents are not saved in SharePoint. Instead their data is stored in SessionState until the user chooses to save. Files are uploaded to an ASMX service, then the browser requests their individual pages via the above ASHX.
Files are uploaded like this in an ASMX service:
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
Public object Upload()
{
var request = HttpContext.Current.Request;
if (request.Files.Count == 1)
{
var uniqueId = request["uniqueId"];
var file = request.Files[0];
using (var memoryStream = new MemoryStream())
{
file.InputStream.CopyTo(memoryStream);
docInfo = UploadItem(uniqueId, pageNum, memoryStream.ToArray());
}
}
}
UploadItem adds the uniqueId and byte[] to SessionState.
Files are sent from javascript like this (FileUpload being tied to the change event of an input of type=file):
this.FileUpload = function (files) {
var upload = new XMLHttpRequest();
upload.onreadystatechange = () => {
if (this._curUploadRequest.readyState == 4) {
// handle response
}
};
UpdateFormDigest((<any>window)._spPageContextInfo.webServerRelativeUrl,(<any>window)._spFormDigestRefreshInterval);
var data = new FormData();
data.append("uniqueId", uniqueId);
data.append("pageNum", pageNum);
data.append("data", files[0]);
upload.open('POST', "myurl");
upload.setRequestHeader("X-RequestDigest", $("#__REQUESTDIGEST").val());
upload.send(data);
};
Now we come to the actual bug.
Images are rendered using:
<img src="url to ASHX service" />
In FireFox and Chrome, page images from uploaded documents always show up just fine. But in IE (9, 10, or 11), it renders only the first portion of them, then shows broken image icons on the image placeholders. For these broken images, the NET tab of IE shows it received 0kb and the error event is hit. But if I put a breakpoint in the ASHX just before it returns the stream, it always has a size.
More interestingly, if you take the url that the src is pointed to, open a new window and paste it in, the image shows up just fine.
I even tried to load the images in javascript first like this:
var img = new Image();
img.onload = function(){
// use jquery to append image to page
};
img.src = "url to ASHX service";
In this scenario, Chrome and Firefox work fine as usual, but IE fails again. Except this way, the NET tab of IE shows it received the correct size kb in response. However, it still shows the broken image icon and won't render images to the screen after some unknown threshold. The first several images come back, but once one breaks, all of the rest break.
I also modified the ASHX service to return base64 data instead of a stream, then bound the base64 to the src. In the debugger you can see the base64 assigned to the src of the img elements that show the broken image icon. So the data is there for sure, but IE just isn't rendering it...
I tried to recreate this problem outside of our SharePoint environment in this fiddle using knockout JS. Basically, I grab a ton of big images and throw them on the screen with each button click. But it works just fine. It works perfectly if I use jQuery too.
http://jsfiddle.net/bsdez92f/
Not sure where to go from here.
Any ideas?
So it turns out that the image size was causing a problem. I scaled the images down to thumbnail size on the server side and returned that to the browser. All is working fine at this point.
I receive a WordProcessingDocument as base64 from my web service.
I am trying now to donwload it in the client side. (HTML/JS)
Javascript
var file = base64String;
var url = 'data:application/msword;base64,' + file;
window.location.href = url;
The word is actually downloading and evertyhing is going well except for one thing.
I got 2 image, one from a the template word and an other one that I programmaticaly add.
The second one is not displayed.
This image cannot currently be displayed
It is maybe link to this "error" that appears when I download the word
Resource interpreted as Document but transferred with MIME type application/msword:
I'm busy writing a handler to serve various documents for download or presentation in web forms pages. The documents range from various image formats, to PDF, to MS Office documents, to generic binaries. My basic draft of the download process is as below:
public void ProcessRequest(HttpContext context)
{
var docUrl = context.Request["docUrl"];
if (string.IsNullOrEmpty(docUrl)) {
context.Response.End();
return;
}
var docPath = context.Server.MapPath(docUrl);
var docInfo = new FileInfo(docPath);
context.Response.Clear();
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(docPath));
context.Response.AddHeader("Content-Length", docInfo.Length.ToString());
context.Response.ContentType = "application/octet-stream";
context.Response.WriteFile(docPath);
context.Response.End();
}
However, I have some misgivings about lumping all documents together as application/octet-stream, and I would prefer, if feasible, to use a more specific content type per document type. I have a DB table for document types where I could store this. Am I going in the right direction, and if so, where can I find a suitable starting list of content types for document types?
application/octet-stream is fine for file downloading, but if you want the browser to interact with the file, you might want to change the content type.
For example, the mime-type for downloading a PDF file is application/octet-stream, while application/pdf will tell the browser to open the file in the browser itself.
http://en.wikipedia.org/wiki/Internet_media_type