Implement POC for image embedding #509

Open
mgreter wants to merge 3 commits from mgreter/master into master
mgreter commented 2016-11-29 10:07:36 +00:00 (Migrated from github.com)

Hi all

I've had the same feature wish as https://github.com/SheetJS/js-xlsx/issues/364 and https://github.com/SheetJS/js-xlsx/issues/137 to be able to embed some images in WorkSheets. Took me a few hours to get something up and running and I thought I'd share the results here. Unfortunately this project seems rather dead, so I did not put too much effort into this Pull Request. I might refine it a bit more once I'm actually start using it. For now I just made all changes in the main joined source file!

I also found a similar PR in another fork: https://github.com/protobi/js-xlsx/pull/19

Usage:

workbook.Sheets['my-sheet']['!images'] = [
	{
		name: 'image1.jpg',
		data: image[0].base64,
		opts: { base64: true },
		position: {
			type: 'twoCellAnchor',
			attrs: { editAs: 'oneCell' },
			from: { col: 2, row : 2 },
			to: { col: 6, row: 5 }
		}
	},
	{
		name: 'image2.jpg',
		data: image[1].base64,
		opts: { base64: true },
		position: {
			type: 'twoCellAnchor',
			attrs: { editAs: 'oneCell' },
			from: { col: 2, row : 10 },
			to: { col: 6, row: 14 }
		}
	}
];

Very helpfull references:
http://officeopenxml.com/drwOverview.php

Hope it's usefull to some people!

Hi all I've had the same feature wish as https://github.com/SheetJS/js-xlsx/issues/364 and https://github.com/SheetJS/js-xlsx/issues/137 to be able to embed some images in WorkSheets. Took me a few hours to get something up and running and I thought I'd share the results here. Unfortunately this project seems rather dead, so I did not put too much effort into this Pull Request. I might refine it a bit more once I'm actually start using it. For now I just made all changes in the main joined source file! I also found a similar PR in another fork: https://github.com/protobi/js-xlsx/pull/19 Usage: ```js workbook.Sheets['my-sheet']['!images'] = [ { name: 'image1.jpg', data: image[0].base64, opts: { base64: true }, position: { type: 'twoCellAnchor', attrs: { editAs: 'oneCell' }, from: { col: 2, row : 2 }, to: { col: 6, row: 5 } } }, { name: 'image2.jpg', data: image[1].base64, opts: { base64: true }, position: { type: 'twoCellAnchor', attrs: { editAs: 'oneCell' }, from: { col: 2, row : 10 }, to: { col: 6, row: 14 } } } ]; ``` Very helpfull references: http://officeopenxml.com/drwOverview.php Hope it's usefull to some people!
stewartsims commented 2016-12-13 15:24:40 +00:00 (Migrated from github.com)

👍 This would be very useful for a project we are involved with and as far as I can see from some research the only viable existing implementation for writing 'drawings' into spreadsheet documents in the browser. If the maintainers of this project are watching, please review these changes and merge if possible. I will test this out for our requirements.

👍 This would be very useful for a project we are involved with and as far as I can see from some research the only viable existing implementation for writing 'drawings' into spreadsheet documents in the browser. If the maintainers of this project are watching, please review these changes and merge if possible. I will test this out for our requirements.
stewartsims commented 2016-12-14 14:44:53 +00:00 (Migrated from github.com)

I have tested and this works fine. Took me a little while to realise I needed to chop off the 'data: image/png...' header and just supply the base64 string itself.

Of course further functionality could be added to improve - for example different options other than 'twoCellAnchor' for positional layout of the image. But this seems like a good approach to me and relatively low risk?

I have tested and this works fine. Took me a little while to realise I needed to chop off the 'data: image/png...' header and just supply the base64 string itself. Of course further functionality could be added to improve - for example different options other than 'twoCellAnchor' for positional layout of the image. But this seems like a good approach to me and relatively low risk?
mgreter commented 2016-12-14 17:37:35 +00:00 (Migrated from github.com)

Thanks for trying it out. I will unfortunately not use this library in the foreseeable future myself, so I don't intend to further improve this PR. As you figured out, most edges are not polished and would need further work/documentation. Sadly I don't expect the repo owner to merge this anytime, given the list of other open PRs and Issues. But cool to hear that you got it working 👍 !

If anyone wants to add more functionality to this PR, feel free to create a PR against my branch, so it will also be visible/included here.

Thanks for trying it out. I will unfortunately not use this library in the foreseeable future myself, so I don't intend to further improve this PR. As you figured out, most edges are not polished and would need further work/documentation. Sadly I don't expect the repo owner to merge this anytime, given the list of other open PRs and Issues. But cool to hear that you got it working 👍 ! If anyone wants to add more functionality to this PR, feel free to create a PR against my [branch][1], so it will also be visible/included here. [1]: https://github.com/mgreter/js-xlsx
stewartsims commented 2016-12-15 09:23:20 +00:00 (Migrated from github.com)

Understood - I wouldn't really expect you to add more functionality to this - but I think it will prove useful for us so thanks for submitting it to this project. As you say the seems to be stagnant for now, I'll keep an eye on it and try to get involved if I can in future.

Understood - I wouldn't really expect you to add more functionality to this - but I think it will prove useful for us so thanks for submitting it to this project. As you say the seems to be stagnant for now, I'll keep an eye on it and try to get involved if I can in future.
stewartsims commented 2016-12-15 13:17:34 +00:00 (Migrated from github.com)

Found a couple issues with using multiple images, all easily resolvable. Will create a PR against your version shortly.

Found a couple issues with using multiple images, all easily resolvable. Will create a PR against your version shortly.
mgreter commented 2016-12-15 17:09:25 +00:00 (Migrated from github.com)

Thanks @stewartsims for the PR. I've merged it and your changes should be part of this PR now 🚀

For completeness I'll include @stewartsims comments below:

  • I noticed when using multiple images the first one was repeated: just a couple places where the index of the image was not being respected during iteration

  • Added the addition from another PR for specifying row height e.g.

ws['!rows'] = [
    {hpx:275},
    {hpx:100},
    {hpx:100}
];
  • I found the keys method threw an error in some situations when it was being passed a 'null' argument, just made it more defensive but possibly a symptom of a problem elsewhere in the code
Thanks @stewartsims for the PR. I've merged it and your changes should be part of this PR now 🚀 For completeness I'll include @stewartsims comments below: - I noticed when using multiple images the first one was repeated: just a couple places where the index of the image was not being respected during iteration - Added the addition from another PR for specifying row height e.g. ``` ws['!rows'] = [ {hpx:275}, {hpx:100}, {hpx:100} ]; ``` - I found the keys method threw an error in some situations when it was being passed a 'null' argument, just made it more defensive but possibly a symptom of a problem elsewhere in the code
tarwich commented 2016-12-17 03:51:58 +00:00 (Migrated from github.com)

Hey, guys. Can you add a pull request to tarwich/js-xlsx? To be honest, I haven't read this fully, but I see it's needed. I don't have a lot of time to maintain, but I'm trying to merge in these pull requests in order to keep the ball rolling for the community. Also, if anyone wants to help I'll be happy to add them.

I drafted a pull request here, so if it's what is needed, I'll go with it.
https://github.com/tarwich/js-xlsx/compare/master...mgreter:master

Hey, guys. Can you add a pull request to [tarwich/js-xlsx]? To be honest, I haven't read this fully, but I see it's needed. I don't have a lot of time to maintain, but I'm trying to merge in these pull requests in order to keep the ball rolling for the community. Also, if anyone wants to help I'll be happy to add them. [tarwich/js-xlsx]: https://github.com/tarwich/js-xlsx I drafted a pull request here, so if it's what is needed, I'll go with it. https://github.com/tarwich/js-xlsx/compare/master...mgreter:master
stewartsims commented 2016-12-19 09:22:31 +00:00 (Migrated from github.com)

OK I've submitted a PR with details of the changes @tarwich - hope that helps.

OK I've submitted a PR with details of the changes @tarwich - hope that helps.
tarwich commented 2016-12-20 05:32:48 +00:00 (Migrated from github.com)

Merged

Merged
mgreter commented 2016-12-22 21:28:46 +00:00 (Migrated from github.com)

Thanks @tarwich. FWIW I thought I might add how I used this lib in my POC.
Basic request was to enter data and take pictures on mobile and store as excel.
With js-xlsx and this PR it was quite easy to do so!
It's not self contained but you should get the idea:

<!-- this is part of an angular2 template -->
<input type="file" accept="image/*" capture="camera" (change)="onPicChange(pic)" #pic />
// method is part of a class!
onPicChange(data: any) : void {
  var self = this;
  var reader  = new FileReader();
  reader.addEventListener("load", function () {

    var img = new Image();
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");

    img.onload = function()
    {
      var maxWidth = 300;
      var width = img.width;
      var height = img.height;
      if (width > maxWidth) {
        height *= maxWidth / width;
        width = maxWidth;
      }
      canvas.width = width;
      canvas.height = height;
      ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height);
      self.picSrc = canvas.toDataURL("image/jpeg");
      self.picBlob = self.picSrc.split(',')[1];
    }

    img.src = reader.result;

  }, false);
  reader.readAsDataURL(data.files[0]);
}

Then it follow the example given initially:

workbook.Sheets['Order-' + id]['!images'] = [
  { name: 'image1.jpg',
    data: this.picBlob,
    opts: { base64: true },
    position: {
      type: 'twoCellAnchor',
      attrs: { editAs: 'oneCell' },
      from: { col: 2, row : 2 },
      to: { col: 6, row: 5 }
    }
   },

I also stored the image data in an offline storage in base64 (not efficient, but works).

HTH

Thanks @tarwich. FWIW I thought I might add how I used this lib in my POC. Basic request was to enter data and take pictures on mobile and store as excel. With js-xlsx and this PR it was quite easy to do so! It's not self contained but you should get the idea: ```html <!-- this is part of an angular2 template --> <input type="file" accept="image/*" capture="camera" (change)="onPicChange(pic)" #pic /> ``` ```js // method is part of a class! onPicChange(data: any) : void { var self = this; var reader = new FileReader(); reader.addEventListener("load", function () { var img = new Image(); var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); img.onload = function() { var maxWidth = 300; var width = img.width; var height = img.height; if (width > maxWidth) { height *= maxWidth / width; width = maxWidth; } canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height); self.picSrc = canvas.toDataURL("image/jpeg"); self.picBlob = self.picSrc.split(',')[1]; } img.src = reader.result; }, false); reader.readAsDataURL(data.files[0]); } ``` Then it follow the example given initially: ```js workbook.Sheets['Order-' + id]['!images'] = [ { name: 'image1.jpg', data: this.picBlob, opts: { base64: true }, position: { type: 'twoCellAnchor', attrs: { editAs: 'oneCell' }, from: { col: 2, row : 2 }, to: { col: 6, row: 5 } } }, ``` I also stored the image data in an offline storage in base64 (not efficient, but works). HTH
willemmulder commented 2017-01-06 08:26:34 +00:00 (Migrated from github.com)

It would be great if this could be merged!

It would be great if this could be merged!
JohnRSim commented 2017-03-17 09:37:02 +00:00 (Migrated from github.com)

I agree would be great if this could be merged in.. 👍

I agree would be great if this could be merged in.. 👍
SheetJSDev commented 2017-03-21 04:58:13 +00:00 (Migrated from github.com)

Here's a quick sample to test a few features:

BIFF8 XLS

BIFF5 XLS

XLSX

XLSB

XLML

ODS

FODS

The different workbook formats use different image filetypes (is that really a surprise?), like BMP and WMF/PICT and PNG/JPG and PDF.

Immediately a few things stand out:

  1. Mandate a specific image format or allow any image format?

  2. The files are referenced at a workbook level, so we need a structure for supporting those assets. Probably have an assets hash at the workbook level, use strings in the worksheet !images to reference the assets.

  3. Which features should be supported? For example, Excel 2016 supports certain 3d effects.

@mgreter as you probably saw, it's not hard to set up the relevant fields in the XLSX to make the feature work; the challenging question is settling on a sensible representation

Here's a quick sample to test a few features: [BIFF8 XLS](https://gist.githubusercontent.com/SheetJSDev/ba7b8f59a19a5819d77303e1c97c28a1/raw/b17d8c8a84ed3496dd7801db6207aebcc47269d0/picture_test.xls) [BIFF5 XLS](https://gist.githubusercontent.com/SheetJSDev/ba7b8f59a19a5819d77303e1c97c28a1/raw/b17d8c8a84ed3496dd7801db6207aebcc47269d0/picture_test5.xls) [XLSX](https://gist.githubusercontent.com/SheetJSDev/ba7b8f59a19a5819d77303e1c97c28a1/raw/b17d8c8a84ed3496dd7801db6207aebcc47269d0/picture_test.xlsx) [XLSB](https://gist.githubusercontent.com/SheetJSDev/ba7b8f59a19a5819d77303e1c97c28a1/raw/b17d8c8a84ed3496dd7801db6207aebcc47269d0/picture_test.xlsb) [XLML](https://gist.githubusercontent.com/SheetJSDev/ba7b8f59a19a5819d77303e1c97c28a1/raw/b17d8c8a84ed3496dd7801db6207aebcc47269d0/picture_test.xml) [ODS](https://gist.githubusercontent.com/SheetJSDev/ba7b8f59a19a5819d77303e1c97c28a1/raw/b17d8c8a84ed3496dd7801db6207aebcc47269d0/picture_test.ods) [FODS](https://gist.githubusercontent.com/SheetJSDev/ba7b8f59a19a5819d77303e1c97c28a1/raw/b17d8c8a84ed3496dd7801db6207aebcc47269d0/picture_test.fods) The different workbook formats use different image filetypes (is that really a surprise?), like BMP and WMF/PICT and PNG/JPG and PDF. Immediately a few things stand out: 1) Mandate a specific image format or allow any image format? 2) The files are referenced at a workbook level, so we need a structure for supporting those assets. Probably have an assets hash at the workbook level, use strings in the worksheet `!images` to reference the assets. 3) Which features should be supported? For example, Excel 2016 supports certain 3d effects. @mgreter as you probably saw, it's not hard to set up the relevant fields in the XLSX to make the feature work; the challenging question is settling on a sensible representation
oreillyj1 commented 2017-04-25 17:28:06 +00:00 (Migrated from github.com)

apologies on this but is there a small complete example of exporting html table data to XLSX (with a image in it)? somewhere out there ...a jsfiddle or something...

apologies on this but is there a small complete example of exporting html table data to XLSX (with a image in it)? somewhere out there ...a jsfiddle or something...
FrankBirik commented 2017-04-28 14:56:46 +00:00 (Migrated from github.com)

Hi,
Can I have a bit more explanation on !images? I added it but it gives me cannot set property

"The files are referenced at a workbook level, so we need a structure for supporting those assets. Probably have an assets hash at the workbook level, use strings in the worksheet !images to reference the assets."

Hi, Can I have a bit more explanation on !images? I added it but it gives me cannot set property "The files are referenced at a workbook level, so we need a structure for supporting those assets. Probably have an assets hash at the workbook level, use strings in the worksheet !images to reference the assets."
PranayShah commented 2017-05-31 08:44:04 +00:00 (Migrated from github.com)

This works perfectly fine for me. I am using xSirrioNx's fork and had to merge in minor changes from @stewartsims commits to support images on multiple sheets. The image (a PNG) however stretches (not even scale proportionately) to the cell's dimensions. Is it possible to fix dimensions for the image?

This works perfectly fine for me. I am using xSirrioNx's fork and had to merge in minor changes from @stewartsims commits to support images on multiple sheets. The image (a PNG) however stretches (not even scale proportionately) to the cell's dimensions. Is it possible to fix dimensions for the image?
bys-wallance-zhang commented 2017-07-25 12:05:51 +00:00 (Migrated from github.com)

@mgreter ,
Hi mgreter,I find 2 issues, one is the image only be inserted 1st sheet, if add the 2nd the image not be present in export file;
another issue is when heperlink and image add the same sheet, the image will be removed from the export file

@mgreter , Hi mgreter,I find 2 issues, one is the image only be inserted 1st sheet, if add the 2nd the image not be present in export file; another issue is when heperlink and image add the same sheet, the image will be removed from the export file
dbgtx commented 2017-11-15 21:23:19 +00:00 (Migrated from github.com)

So I tried the @mgreter solution as listed above & his xlsx.js fork. The 3 JPEGs I tried get corrupted since I get the following error when opening the xlsx in Excel2013/16:
"We found a problem in some of the content in 'text.xlsx'. Do you want to recover as much as we can?...."

After clicking: YES, I'm notified:
Removed Part: Drawing shape. error code:

<removedParts summary="Following is a list of removed parts:">
<removedPart>Removed Part: Drawing shape.</removedPart>
</removedParts>

When looking at the xlsx zipped package before agreeing to the above, the image does appear inside the media folder, but isn't readable either. Any suggestions? What am I missing?

So I tried the @mgreter solution as listed above & his xlsx.js fork. The 3 JPEGs I tried get corrupted since I get the following error when opening the xlsx in Excel2013/16: "We found a problem in some of the content in 'text.xlsx'. Do you want to recover as much as we can?...." After clicking: YES, I'm notified: Removed Part: Drawing shape. error code: ``` <removedParts summary="Following is a list of removed parts:"> <removedPart>Removed Part: Drawing shape.</removedPart> </removedParts> ``` When looking at the xlsx zipped package before agreeing to the above, the image does appear inside the media folder, but isn't readable either. Any suggestions? What am I missing?
gauravsbagul commented 2021-04-01 07:29:51 +00:00 (Migrated from github.com)

hi all,
Is there any alternative way to add an image to the sheet, any other alternate package? My company is not willing to paying for the feature.

hi all, Is there any alternative way to add an image to the sheet, any other alternate package? My company is not willing to paying for the feature.
ibraahim6 commented 2021-08-30 01:42:59 +00:00 (Migrated from github.com)

hello @gauravsbagul ,
Did you find any solution for this problem?

hello @gauravsbagul , Did you find any solution for this problem?
chenasraf commented 2022-03-15 14:04:29 +00:00 (Migrated from github.com)

Any update on this? Could really use this feature... :)

Any update on this? Could really use this feature... :)
This pull request has changes conflicting with the target branch.
  • xlsx.js

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin mgreter/master:mgreter/master
git checkout mgreter/master

Merge

Merge the changes and update on Gitea.
git checkout master
git merge --no-ff mgreter/master
git checkout master
git merge --ff-only mgreter/master
git checkout mgreter/master
git rebase master
git checkout master
git merge --no-ff mgreter/master
git checkout master
git merge --squash mgreter/master
git checkout master
git merge mgreter/master
git push origin master
Sign in to join this conversation.
No description provided.