PHP Spreadsheet: After saving data to a new worksheet, the data of the previous worksheets are deleted - phpspreadsheet

I am creating a script to save CSV data into an excel document, but in different worksheets, I mean, every CSV doc will go into a new worksheet, but after saving data to a new worksheet the previous data that are in the other worksheets are deleted. This is my code
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$spreadsheet = new Spreadsheet();
$spreadsheet2 = new Spreadsheet();
$reader = new PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $reader->load('test.xlsx');
$numSheets = $spreadsheet -> getSheetCount();
$reader2 = new PhpOffice\PhpSpreadsheet\Reader\Csv();
/* Set CSV parsing options */
$reader2->setDelimiter(',');
$reader2->setEnclosure('"');
$reader2->setSheetIndex($numSheets);
echo $numSheets;
/* Load a CSV file and save as a XLS */
$spreadsheet2 = $reader2->load('testcsv.csv');
$writer = new Xlsx($spreadsheet2);
$writer->save('test.xlsx');
$spreadsheet->disconnectWorksheets();
unset($spreadsheet);
?>
With this only the last worksheet have data
enter image description here
I want to emphasize that I have no errors but I am not achieving what I want to do

The problem is that you use
$numSheets = $spreadsheet -> getSheetCount();
but you must count your sheet numbers and add a new sheet in your file.
I would suggest you use a loop.
$numSheets = $spreadsheet -> getSheetCount();
foreach($csvs as $csv){
// Create a new worksheet called "My Data"
$myWorkSheet = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, 'My Data');
// Attach the "My Data" worksheet as the first worksheet in the Spreadsheet object
$spreadsheet->addSheet($myWorkSheet, $numSheets);
$numSheets++;
}
More information here

Related

How to conditionally change values of a Google Sheet using another Sheet

I am trying to modify an existing Google Sheet using a Form response sheet. Suppose in the sheet I need modified I have column G called "Annotated Asset ID" which contains a list of asset IDs. Now in the form response sheet there are two columns; Old ID (D) and New ID (E). I would like to check Column G of the existing sheet to see if it contains the Old ID and if it does I need to replace it with the New ID.
What is a good way to do this?
Form Response:
Existing Sheet:
Answer:
You can do this with Apps Script.
Steps:
Extract out the old and new IDs from the form response sheet
For each of the old IDs, use a TextFinder to search your column for the old ID in the existing sheet:
const cell = sheet.getRange("G1:G").createTextFinder("old-id").findNext()
Replace the ID if cell isn't null:
if (cell) { cell.setValue("new-id") }
Code Example:
function replaceIds() {
const ss = SpreadsheetApp.getActiveSpreadsheet()
const formResponseSheet = ss.getSheetByName("response-sheet-name")
const existingSheet = ss.getSheetByName("existing-sheet-name")
const oldIds = formResponseSheet.getRange("D1:D").getValues().flat()
const newIds = formResponseSheet.getRange("E1:E").getValues().flat()
const rangeToCheck = existingSheet.getRange("G1:G")
oldIds.forEach(function(id, index) {
let cell = rangeToCheck.createTextFinder(id).findNext()
if (cell) {
cell.setValue(newIds[index])
}
})
}
Add this to your project from the Tools > Script editor menu item. Make sure to change the response sheet nad existing sheet names.
Save the script and run the function. You will need to authorise it to run on your behalf.

Create Multiple Campaign From MYSQL Query

have a MYSQL database and I would like to add new campaign for each row I have in the MYSQL table.
The code below creates only one campaign, but I want to create multiple campaigns e.g. each row in the table should be used to create new campaign, please advise.
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
$sql = "SELECT * FROM table";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()) {
// Create a campaign with required and optional settings.
$campaign = new Campaign();
$campaign->setName($row["name"]. uniqid());
$campaign->setAdvertisingChannelType(AdvertisingChannelType::SEARCH);
}

How to get all sheet names without trimming?

I have excel file with sheet names utf-8, and I got trimmed sheet name because this sheet title is more then 31 characters.
My code:
<?php
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
$reader = IOFactory::createReader('Xlsx');
$reader->setReadDataOnly(TRUE);
$spreadsheet = $reader->load('/home/cool-file.xlsx');
$all = $spreadsheet->getSheetNames();
In $all variable I got a list of all sheet names but all names are trimmed.
I tried to comment this part of code:
https://github.com/PHPOffice/PhpSpreadsheet/blob/develop/src/PhpSpreadsheet/Worksheet/Worksheet.php#L853-L882
but no changes.
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
$reader = IOFactory::createReader('Xlsx');
$reader->setReadDataOnly(TRUE);
$spreadsheet = $reader->load('/home/cool-file.xlsx');
$all = $spreadsheet->getSheetNames()[1];
Please, note the bracket and the ID of the sheet

How to generate Excel form EPPluse which has group column header

I want to generate excel sheet from EPPluse which has group column header like below picture.Then How to build DataTable which handle this situation. please help me to get it done easily.
Thanks in advance
You want to use the Merge property on the ExcelRange object.
Here's an example:
using (var pck = new ExcelPackage(new FileInfo(#"c:\temp\Book1.xlsx")))
{
var ws = pck.Workbook.Worksheets["Sheet1"] ?? pck.Workbook.Worksheets.Add("Sheet1");
var rng = ws.Cells["BO1:BQ1"];
rng.Merge = true;
rng.Value = "Answer for Att 3";
pck.Save();
}
You can use this code to write your group headers, then use ExcelRange's LoadFromDataTable() method to write your DataTable directly to the worksheet starting from cell A2

Reading Excel using C# and OleDB - How to identify the used range?

I am reading an Excel file using good old OleDBConnections and OleDBCommands. How do I identify the used range of the excel sheet?
For example, if I were to use InterOp, I can always do this -
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xWb;
Excel.Worksheet xWs;
Excel.Range range;
xWb = xlApp.Workbooks.Open(#"D:\Technical\C#\WorkingFolder\HelloWorld.xls", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xWs = (Excel.Worksheet)xWb.Worksheets.get_Item(1);
range = xWs.UsedRange;
Now, I get a list of all the used columns. With OleDB, how do I get it. Now, even if I were to nail down the column list, how will I know that the rows end here.
Basically, my requirement is this.
I am about to receive an Excel (2003) file. The data will always include Headers (i.e., column name). It does not mean that the data will always be populated from A1:J200
It can also be from A5:J204 too.
So, in using OleDBCommand
string sConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Technical\C#\WorkingFolder\HelloWorld.xls;Extended Properties=""Excel 8.0;HDR=YES;""";
string sCommandString = "SELECT Employee_Id, First_Name FROM [Sheet1$A1:J200]";
OleDbConnection xlConnection = new OleDbConnection(sConnectionString);
xlConnection.Open();
OleDbCommand xlCommand = new OleDbCommand(sCommandString, xlConnection);
OleDbDataAdapter tempDataAdapter = new OleDbDataAdapter();
tempDataAdapter.SelectCommand = xlCommand;
DataTable tempDataTable = new DataTable("Whatever_I_Want");
tempDataAdapter.Fill(tempDataTable);
Now, the line
sCommandString has the hardcoded value of A1:J200, what if the excel I receive has the data range as A5:204, what will I do?
Any help would be great!
Untried but I think you could do it by first creating a DataAdapter with a SELECT * FROM [Sheet] statement and then use that in a call to FillSchema after which you should be able to call .Columns.Count on the DataTable you just filled.

Resources