I am trying to copy a workbook with multiple sheets into a single sheet. I have found other libraries that work fine for copying ranges or sheets into the bottom of another but they don't copy the images. Is this possible with EPPlus? If it isn't are there other libraries that do this?
I was able to get this accomplished by using GemBox.Spreadsheet. The were quite responsive to bug(s) in their library and it all functions correctly now.
var excelDrawings = sheet1.Drawings.Where(x => x.DrawingType ==
eDrawingType.Picture).ToList();
foreach (var excelDrawing in excelDrawings)
{
var name = excelDrawing.Name;
var image = excelDrawing.As.Picture.Image;
singleSheet.Drawings.AddPicture(name, image);
}
Related
I have several PDF documents that supposedly contain scanned images, but upon inspection in Acrobat Pro, each page contains a huge number of tiny "inline images". From what I understand these are not regular images inside XObjects, but rather images embedded directly inside content streams.
How could I go about extracting and merging these images?
The only code I could find online starts out like this:
var reader = new PdfReader(#"path\to\file.pdf");
PdfDocument document = new PdfDocument(reader);
for (var i = 1; i <= document.GetNumberOfPages(); i++)
{
PdfDictionary obj = (PdfDictionary)document.GetPdfObject(i);
// ... more code goes here
}
...but the rest of the code doesn't work because the PdfDictionary returned from GetPdfObject is not a stream, only a dictionary. I don't know how to access the images inside it.
I have linked part of a sheet in google doc (as linked object). Now, whenever I change the sheet data, I can click a button in google doc and the data is reflected in the google doc linked sheet too (this is all built in google doc stuff).
What I want to do is the other side of this. I am able to see a bunch of data in one place (google doc) based on the sheets I have linked. I would like to update the data in the google doc, and "upload" it to the linked google sheets.
I am trying to write a script to do that. But cannot seem to find any method to access linked sheets. I found this slides API page that can does the sheet -> slide syncing.
I am looking at the document API page, but I scanning through add... and get... methods, I don't see to find any way to get linked objects. Is it represented as NamedRange? If so, how do I access it?
There was another similar question, but without any satisfactory answer.
If you can share some pointers to get started, I would appreciate it.
Edit: Here is an example doc (and a spreadsheet contained their in) to explain the situation clearer.
Test document for updating spreadsheet - Google Docs
You can find the Table elements in your Document via findElement(elementType). If that's the only Table in your Document, as in the sample you shared, this is immediate.
Once you retrieve the Table, you can loop through its rows and cells and come up with a 2D array with the values from the table:
function getTableValues() {
const doc = DocumentApp.getActiveDocument();
const body = doc.getBody();
const table = body.findElement(DocumentApp.ElementType.TABLE).getElement();
let tableValues = [[]];
for (let i = 0; i < table.getNumRows(); i++) {
const tableRow = table.getRow(i);
for (let j = 0; j < tableRow.getNumCells(); j++) {
const tableCell = tableRow.getCell(j);
const text = tableCell.getText();
tableValues[i].push(text);
}
if (i == table.getNumRows() - 1) break;
tableValues.push([]);
}
return tableValues;
}
Once you've done that, you just need to copy it to your spreadsheet via setValues(values):
function copyToSheet(tableValues, spreadsheetId) {
const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName("Sheet1");
sheet.getRange(1, 1, tableValues.length, tableValues[0].length).setValues(tableValues);
}
Calling both of these in the same function, you would get this:
function main() {
const tableValues = getTableValues();
const spreadsheetId = "{your-spreadsheet-id}";
copyToSheet(tableValues, spreadsheetId);
}
Note:
getActiveDocument() is used to retrieve the Document, so this assumes the script is bound to your Document. If that's not the case, use openById(id) or openByUrl(url) instead.
function extractTextFromPDF() {
// PDF File URL
// You can also pull PDFs from Google Drive
// this Fall2019_LLFullCatalog.pdf will not insert - internal error on insert is all the feedback that gets logged"
// doesn't matter if I retrieve it from the university website or if I first copy it to my google drive and then retrieve it from there
//var url = "https://uwf.edu/media/university-of-west-florida/offices/continuing-ed/leisure-learning/docs/Fall2019_LLFullCatalog.pdf";
//var url = "https://drive.google.com/drive/u/0/my-drive/Fall2019_LLFullCatalog.pdf";
// both of these pdfs will insert just fine. Size is not the issue because this one is much larger than the one I need to insert
var url = "https://eloquentjavascript.net/Eloquent_JavaScript_small.pdf";
//var url = "https://img.labnol.org/files/Most-Useful-Websites.pdf";
var blob = UrlFetchApp.fetch(url).getBlob();
var size = blob.getBytes().length;
var resource = {
title: blob.getName(),
mimeType: blob.getContentType()
};
// Enable the Advanced Drive API Service
var file = Drive.Files.insert(resource, blob, {ocr: true, ocrLanguage: "en"});
// Extract Text from PDF file
var doc = DocumentApp.openById(file.id);
var text = doc.getBody().getText();
return text;
}
See comments in code above that describe the problem.
The PDF that I need to insert with OCR is not working - regardless of whether I retrieve it from the original site or retrieve a copy that I put on google drive. However, two other PDF urls will insert just fine and one of them is considerably larger than the one that fails.
What else could be the issue, if not size limitation?
Thanks,
Steve
It could very well be a bug in the Chrome API. Not all PDF software is created equal, check if the PDF can be read in Adobe Acrobat as a simple test.
I have an image with longitude and latitude coordinates, can any one tell me how do i get it? I have tried
if (CrossMedia.Current.IsPickPhotoSupported)
{
MediaFile photoPicked = await CrossMedia.Current.PickPhotoAsync();
if (photoPicked != null)
{
//await DisplayAlert("Photo Location", photoPicked.Path, "OK");
//path = photoPicked.Path;
using (Stream streamPic = photoPicked.GetStream())
{
var picInfo = ExifReader.ReadJpeg(streamPic);
ExifOrientation orientation = picInfo.Orientation;
//MainImage123.Source = ImageSource.FromStream(() => photoPicked.GetStream());
latitude = picInfo.GpsLatitude;
longitude = picInfo.GpsLongitude;
var filepath = photoPicked.AlbumPath;
var filepath1 = photoPicked.Path;
}
}
}
It works when I picked photo and trying to get its coordinates, but I have to take multiple photos from image gallery and find its coordinates.
does any one know how to read image geo coordinates? please help me.
You can use the ExifLib.PCL Nuget Package to read an image metada, by viewing your "code sample", i think you are using the Plugin.Media to take images/get images from the galery, be sure to use SaveMetaData = true when taking an photo from your app.
Once you have set the SaveMetaData to true, use the ExifLib to obtain the MetaData like this:
MediaFile photo;
using (Stream streamPic = photo.GetStream())
{
var picInfo = ExifReader.ReadJpeg(streamPic);
double lat = picInfo.GpsLatitude;
double lon = picInfo.GpsLongitude;
}
Also, as a plus, you have even more info on the photo (date taken, author, size, etc.).
UPDATE:
After Reading it again, it seems that the problem is that you are not able to pick multiple images from the galery, and NOT being able to get the lat and lon from the photos. At the moment, Plugin.Media doesn't support multi-picking.
Your question was unclear however - I think you are trying to make it work with multiple images together. How you can be able to pick multiple images together?
The plugin "CrossMedia" doesn't support picking up multiple images.
Your solution requires a lot of work to be done to be able to Pickup multiple images at once. So Follow this nice step-by-step tutorial here:
https://xamgirl.com/select-multiple-images-from-gallery-in-xamarin-forms/
With above you will be able to get all the images you need at once.
After you get List, all you have to do is to loop through those images and call your existing code.
Maybe this is one of the impossible ones, but here goes.
I have a ton of images of qr-codes in a folder. It doesnt matter if its in google drive or in a local folder for me.
I would a script that automaticly loads all images in column A and then the file names in column B. AND automaticly adds new images when uploaded to the google drive folder.
Example:
Qr1.jpeg will be loaded into cell a1 and cell b1 will be "Qr1"
Qr2.jpeg will be loaded into cell a2 and so on..
It would be nice if the images are scaled to 10x10 cm. :)
Is this even possible?
Hope you guys can help!
Thanks!
Oliver
Not the Complete Answer...but it's a part
I've been working on getting thumbnails into my spreadsheet ever since you asked this question. I won't go into all the paths I took but I finally found this Github link in the comments of this issue
Which resulted in the following code:
function myImageFiles()
{
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('MyImages');
var files = DriveApp.getFiles();
var s='';
var cnt=1;
while(files.hasNext())
{
var fi=files.next();
var type=fi.getMimeType();
if(type==MimeType.GIF || type==MimeType.JPEG || type==MimeType.PNG)
{
sh.appendRow([cnt++,fi.getName(),type,fi.getUrl(),'=IMAGE("' + getThumbNailLink(fi.getId()) + '",1)']);
}
}
}
function getThumbNailLink(fileId)
{
var file=Drive.Files.get(fileId);
return file.thumbnailLink;
}
The result is now I have a spreadsheet with all of my image filenames and thumbnails. You'll need Advanced Drive and take a close look at getThumbNailLink().