Amazon Logo

Amazon Bulk Sheet Generator

Built by Rakshit Vaish — Generate Amazon Sponsored Products bulk upload sheets with ease

Structure Preview
Account Type
Seller
Products --
Campaigns --
Ad Groups --
Campaign Structure
Single Product Campaigns
Single Product Ad Groups
Targeting
Settings
Daily Budget $50
Default Bid $0.75
Bidding Down Only
State enabled
Est. Total Rows --

Account Type

one per line

Format: ASIN,SKU,Group (Group optional)

CSV or Excel with ASIN, SKU, Group columns

Campaign Structure & Naming

Ad Group Structure & Naming

Targeting Types

Select all targeting types to generate. At least one must be selected.

Auto Targeting Groups

Close Match: Keywords closely related to your product · Loose Match: Keywords loosely related · Substitutes: Products that are substitutes for yours · Complements: Products that complement yours

Unchecked groups = created as paused

Keyword Targeting

Exact: Search term must match keyword exactly, word-for-word
Phrase: Search term must contain the keyword phrase in order
Broad: Search term can contain words in any order, include synonyms

Placement Adjustments

0 = no adjustment row. Range: 0-900%.

Negative Keywords (optional)

Applied to Keyword & Auto ad groups only (not PT ad groups)

Negative Product Targeting (optional)

Ad group level only. Applied to PT & Auto ad groups (not Keyword ad groups)

One ASIN per line. Generates asin="B07..." expressions.

// ========================================== // DASHBOARD UI OVERRIDE // ========================================== // State to track which campaigns are expanded and which tab is active var dashboardState = {}; // { campaignName: { expanded: bool, activeTab: 'Ad Groups' } } function toggleCampaignExpand(cName) { if (!dashboardState[cName]) dashboardState[cName] = { expanded: false, activeTab: 'Ad Groups' }; dashboardState[cName].expanded = !dashboardState[cName].expanded; renderEditorTable(); } function setCampaignTab(cName, tab) { if (!dashboardState[cName]) dashboardState[cName] = { expanded: true, activeTab: 'Ad Groups' }; dashboardState[cName].activeTab = tab; renderEditorTable(); } function formatMoney(val) { var num = parseFloat(val); if (isNaN(num)) return '-'; return '$' + num.toFixed(2); } function formatNum(val) { var num = parseFloat(val); if (isNaN(num)) return '-'; return num.toLocaleString(); } function formatPct(val) { var num = parseFloat(val); if (isNaN(num)) return '-'; return (num * 100).toFixed(2) + '%'; } function renderDashboardView() { var renderCount = 0; var fEntity = (document.getElementById('editorFilterEntity') || {}).value || 'all'; var fCamp = (document.getElementById('editorFilterCampaign') || {}).value || 'all'; // 1. Build Hierarchy var hierarchy = {}; editorRows.forEach((row, idx) => { var entity = String(row['Entity'] || row['entity']).trim(); var cName = String(row['Campaign Name'] || row['campaign name']).trim(); if (!cName) return; if (!hierarchy[cName]) { hierarchy[cName] = { campaignRow: null, adGroups: [], targeting: [], negatives: [], bidding: [], metrics: { spend: 0, sales: 0, impr: 0, clicks: 0, orders: 0 } }; } row._originalIndex = idx; // Ensure index is tracked if (entity === 'Campaign') { hierarchy[cName].campaignRow = row; } else if (entity === 'Ad Group') { hierarchy[cName].adGroups.push(row); } else if (entity === 'Keyword' || entity === 'Product Targeting') { hierarchy[cName].targeting.push(row); } else if (entity.includes('Negative')) { hierarchy[cName].negatives.push(row); } else if (entity === 'Bidding Adjustment') { hierarchy[cName].bidding.push(row); } // Aggregate metrics if it's a campaign row if (entity === 'Campaign') { hierarchy[cName].metrics.spend = parseFloat(row['Spend'] || row['spend']) || 0; hierarchy[cName].metrics.sales = parseFloat(row['Sales'] || row['sales']) || 0; hierarchy[cName].metrics.impr = parseFloat(row['Impressions'] || row['impressions'] || row['Impr'] || row['impr']) || 0; hierarchy[cName].metrics.clicks = parseFloat(row['Clicks'] || row['clicks']) || 0; hierarchy[cName].metrics.orders = parseFloat(row['Orders'] || row['orders']) || 0; } }); var html = '
'; // Header Row html += `
Campaign
State
Budget/Day
Spend
Sales
ACOS
ROAS
Impr
Clicks
Actions
`; // Sort campaigns by name so cloned campaigns appear under original var sortedCampaignNames = Object.keys(hierarchy).sort(); sortedCampaignNames.forEach(cName => { if (fCamp !== 'all' && cName !== fCamp) return; // Basic filtering var camp = hierarchy[cName]; var state = dashboardState[cName] || { expanded: false, activeTab: 'Ad Groups' }; var row = camp.campaignRow || {}; var idx = row._originalIndex; var rState = String(row['State'] || row['state'] || '').toLowerCase(); // Metrics var spend = camp.metrics.spend; var sales = camp.metrics.sales; var acos = sales > 0 ? (spend / sales) : 0; var roas = spend > 0 ? (sales / spend) : 0; var budgetKey = row['Daily Budget'] !== undefined ? 'Daily Budget' : (row['daily budget'] !== undefined ? 'daily budget' : 'Daily Budget'); var budgetVal = row[budgetKey] !== undefined ? row[budgetKey] : ''; var isCopied = cName.includes('_copied') || cName.includes('_broad') || cName.includes('_exact') || cName.includes('_phrase'); var rowBg = isCopied ? 'bg-indigo-50/20' : 'bg-white'; var modifiedClass = row._isModified ? 'border-l-4 border-l-amber-400' : 'border-l-4 border-l-transparent'; html += `
${cName}
${isCopied ? 'COPIED' : ''}
${formatMoney(spend)}
${formatMoney(sales)}
${sales > 0 ? formatPct(acos) : '-'}
${sales > 0 ? roas.toFixed(2) + 'x' : '-'}
${formatNum(camp.metrics.impr)}
${formatNum(camp.metrics.clicks)}
`; renderCount++; if (state.expanded) { html += `
`; // Tabs html += `
`; // Render active tab content var tabRows = []; if (state.activeTab === 'Ad Groups') tabRows = camp.adGroups; if (state.activeTab === 'Targeting') tabRows = camp.targeting; if (state.activeTab === 'Negative Targets') tabRows = camp.negatives; if (state.activeTab === 'Bidding') tabRows = camp.bidding; if (tabRows.length === 0) { html += `
No ${state.activeTab} found in this sheet for this campaign.
`; } else { html += `
${state.activeTab === 'Targeting' || state.activeTab === 'Negative Targets' ? '' : ''} ${state.activeTab === 'Targeting' || state.activeTab === 'Ad Groups' ? '' : ''} ${state.activeTab === 'Targeting' || state.activeTab === 'Ad Groups' ? '' : ''} `; tabRows.forEach(tr => { renderCount++; var trIdx = tr._originalIndex; var trState = String(tr['State'] || tr['state'] || ''); var trName = tr['Ad Group Name'] || tr['ad group name'] || tr['Keyword Text'] || tr['keyword text'] || tr['Product Targeting Expression'] || tr['product targeting expression'] || '-'; // For targeting, prefix with Ad Group Name if we are in Targeting tab for better context if (state.activeTab === 'Targeting' || state.activeTab === 'Negative Targets') { var agName = tr['Ad Group Name'] || tr['ad group name']; if (agName && agName !== trName) { trName = `${agName}${trName}`; } } var trSpend = parseFloat(tr['Spend'] || tr['spend']) || 0; var trSales = parseFloat(tr['Sales'] || tr['sales']) || 0; var trImpr = parseFloat(tr['Impressions'] || tr['impressions'] || tr['Impr'] || tr['impr']) || 0; var trAcos = trSales > 0 ? trSpend / trSales : 0; var bidKey = tr['Bid'] !== undefined ? 'Bid' : (tr['bid'] !== undefined ? 'bid' : 'Bid'); var trBid = tr[bidKey] !== undefined ? tr[bidKey] : ''; var entityType = String(tr['Entity'] || tr['entity']).trim(); var matchType = String(tr['Match Type'] || tr['match type'] || ''); var displayType = matchType ? matchType : entityType; var stateSelect = ` `; var bidInput = ` `; var trModClass = tr._isModified ? 'bg-amber-50/50' : 'hover:bg-gray-50'; html += ` ${state.activeTab === 'Targeting' || state.activeTab === 'Negative Targets' ? `` : ''} ${state.activeTab === 'Targeting' || state.activeTab === 'Ad Groups' ? `` : ''} ${state.activeTab === 'Targeting' || state.activeTab === 'Ad Groups' ? `` : ''} `; }); html += `
${state.activeTab === 'Targeting' ? 'TARGET' : (state.activeTab === 'Ad Groups' ? 'AD GROUP' : 'NAME')}TYPESTATEBIDSPENDSALESACOSIMPR
${trName}${displayType}${stateSelect}${bidInput}${formatMoney(trSpend)}${formatMoney(trSales)}${trSales > 0 ? formatPct(trAcos) : '-'}${formatNum(trImpr)}
`; } html += `
`; } html += `
`; }); html += '
'; // We update the content of editorTableCard completely. var editorTableCard = document.getElementById('editorTableCard'); if (editorTableCard) { editorTableCard.innerHTML = html; // Make sure to remove any max-h restriction so it can grow or handle scroll itself properly editorTableCard.className = "hidden bg-brand-surface rounded-lg border border-brand-border shadow-sm overflow-auto mt-5 max-h-[800px]"; } return renderCount; } // Override the original renderEditorTable renderEditorTable = renderDashboardView; // Override preset functions to explicitly pause the NEW copied campaign var originalCopyCampaignStructure = copyCampaignStructure; copyCampaignStructure = function(campaignName, newCampaignName) { var newRows = originalCopyCampaignStructure(campaignName, newCampaignName); // Force the new campaign and its ad groups to be paused by default newRows.forEach(r => { var entity = String(r['Entity'] || r['entity']).trim(); if (entity === 'Campaign' || entity === 'Ad Group') { if (r['State'] !== undefined) r['State'] = 'paused'; if (r['state'] !== undefined) r['state'] = 'paused'; } }); return newRows; }; // Also ensure bulk actions disabled properly function getSelectedEditorRowIndices() { // Return empty so the old bulk logic fails gracefully alert("Bulk Actions via checkboxes are not available in Dashboard View. Please edit rows directly or use Presets."); return []; }