You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript将Google Location/OpenWeather API的JSON响应存为并更新CSV文件?

Hey Glen, great question! Let’s break down how to build this feature step by step—here’s a practical implementation plan that covers both frontend and backend scenarios depending on your stack:

Implementation Plan for Generating/Updating CSV from API Responses on Button Click

1. Core Workflow Overview

First, let’s map out the key steps that fire when the user clicks the button:

  • Trigger async API calls to Google Location API and OpenWeather Climate API
  • Wait for both JSON responses to resolve (no race conditions allowed!)
  • Merge and normalize the data into a consistent structure (since the two APIs return very different formats)
  • Convert the combined data into valid CSV format
  • Either download the CSV to the user’s device or update an existing server-stored CSV file

2. Frontend: Button Click & API Calls

Below is a vanilla JavaScript example (adjust for React/Vue/Angular as needed) to handle the button trigger and data fetching:

// Grab the button element
const generateCsvBtn = document.getElementById('generate-csv-btn');

// Store API keys securely (use environment variables in production—never hardcode in frontend!)
const GOOGLE_API_KEY = 'your-google-api-key';
const OPENWEATHER_API_KEY = 'your-openweather-api-key';

// Fetch location data (example: using Geocoding API for a target address)
async function fetchLocationData(address) {
  const response = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${GOOGLE_API_KEY}`);
  if (!response.ok) throw new Error('Failed to load location data');
  return await response.json();
}

// Fetch climate data using coordinates from the Location API response
async function fetchClimateData(lat, lon) {
  const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${OPENWEATHER_API_KEY}&units=metric`);
  if (!response.ok) throw new Error('Failed to load climate data');
  return await response.json();
}

// Main button click handler
generateCsvBtn.addEventListener('click', async () => {
  try {
    // 1. Fetch location data (replace with your target address/coordinates)
    const locationData = await fetchLocationData('Austin, TX');
    const { lat, lng } = locationData.results[0].geometry.location;

    // 2. Fetch climate data using the location coordinates
    const climateData = await fetchClimateData(lat, lng);

    // 3. Normalize and merge data into a CSV-ready object
    const combinedData = {
      location: locationData.results[0].formatted_address,
      latitude: lat,
      longitude: lng,
      temperature: climateData.main.temp,
      humidity: climateData.main.humidity,
      weather_condition: climateData.weather[0].description,
      last_updated: new Date().toISOString()
    };

    // 4. Convert to CSV and trigger download (or send to server to update existing file)
    const csv = convertToCsv([combinedData]); // Wrap in array for multiple entries
    downloadCsv(csv, 'location-climate-data.csv');

  } catch (error) {
    console.error('Error generating CSV:', error);
    alert('Oops! Something went wrong while creating your CSV.');
  }
});

3. JSON to CSV Conversion

You’ll need a helper function to convert your normalized JSON data into valid CSV. This implementation handles edge cases like commas, quotes, and newlines in values:

function convertToCsv(dataArray) {
  if (!dataArray.length) return '';

  // Extract headers from the first object in the array
  const headers = Object.keys(dataArray[0]);

  // Convert each object to a CSV row
  const rows = dataArray.map(obj => {
    return headers.map(header => {
      const value = obj[header] || '';
      // Escape quotes and wrap values in quotes to handle special characters
      return `"${String(value).replace(/"/g, '""')}"`;
    }).join(',');
  });

  // Combine headers and rows into a single CSV string
  return [headers.join(','), ...rows].join('\n');
}

4. CSV File Handling: Two Options

Option A: Download CSV to User’s Device

Add this helper function to trigger a browser download:

function downloadCsv(csvContent, filename) {
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.setAttribute('download', filename);
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

Option B: Update Existing Server-Side CSV

If you need to append data to an existing CSV stored on your server, use a backend endpoint (example with Node.js/Express):

const express = require('express');
const fs = require('fs');
const csvWriter = require('csv-writer').createObjectCsvWriter;

const app = express();
app.use(express.json());

// Endpoint to receive data and update the CSV
app.post('/update-csv', async (req, res) => {
  const newData = req.body;
  const csvFilePath = './location-climate-data.csv';

  try {
    // Check if the CSV exists; append if it does, create new if not
    const fileExists = fs.existsSync(csvFilePath);
    const writer = csvWriter({
      path: csvFilePath,
      header: [
        { id: 'location', title: 'LOCATION' },
        { id: 'latitude', title: 'LATITUDE' },
        { id: 'longitude', title: 'LONGITUDE' },
        { id: 'temperature', title: 'TEMPERATURE' },
        { id: 'humidity', title: 'HUMIDITY' },
        { id: 'weather_condition', title: 'WEATHER_CONDITION' },
        { id: 'last_updated', title: 'LAST_UPDATED' }
      ],
      append: fileExists
    });

    await writer.writeRecords([newData]);
    res.status(200).send('CSV updated successfully');
  } catch (error) {
    console.error('Error updating CSV:', error);
    res.status(500).send('Failed to update CSV');
  }
});

app.listen(3000, () => console.log('Server running on port 3000'));

Then replace the downloadCsv call in your frontend with a POST request to this endpoint:

// Send data to server instead of downloading
await fetch('/update-csv', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(combinedData)
});

5. Critical Production Considerations

  • API Key Security: Never expose API keys in frontend code! Use a backend proxy to forward requests, or restrict key usage to your domain in Google Cloud/OpenWeather dashboards.
  • Data Validation: Add checks for missing fields in API responses (e.g., if (!locationData.results) throw new Error('Invalid location data')) to avoid crashes.
  • CORS: If calling APIs directly from frontend, ensure they allow CORS for your domain. If not, use a backend proxy.
  • Error Handling: Expand error messages to help users troubleshoot (e.g., "Failed to load weather data—check your internet connection").

内容的提问来源于stack exchange,提问作者Glen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:31:31