strapi5-plugin-csv-export
Version:
A powerful Strapi plugin that enables easy export of content types to CSV format, with support for field selection, filtering, and batch operations.
254 lines (253 loc) • 7.18 kB
JavaScript
const bootstrap = ({ strapi }) => {
};
const destroy = ({ strapi }) => {
};
const register = ({ strapi }) => {
};
const config = {
default: {},
validator() {
}
};
const contentTypes = {};
const controller = ({ strapi }) => ({
index(ctx) {
ctx.body = strapi.plugin("csv-export").service("service").getWelcomeMessage();
}
});
const myController = ({ strapi }) => ({
async getDropDownData(ctx) {
ctx.body = await strapi.plugin("csv-export").service("service").getDropDownData();
},
async getTableData(ctx) {
ctx.body = await strapi.plugin("csv-export").service("service").getTableData(ctx);
},
async downloadCSV(ctx) {
ctx.body = await strapi.plugin("csv-export").service("service").downloadCSV(ctx);
}
});
const controllers = {
controller,
myController
};
const middlewares = {};
const policies = {};
const contentAPIRoutes = [
{
method: "GET",
path: "/",
// name of the controller file & the method.
handler: "controller.index",
config: {
policies: []
}
}
];
const adminRoutes = [
{
method: "GET",
path: "/get/dropdown/values",
handler: "myController.getDropDownData",
config: {
policies: [],
auth: false
}
},
{
method: "GET",
path: "/get/table/data",
handler: "myController.getTableData",
config: {
policies: [],
auth: false
}
},
{
method: "GET",
path: "/download/csv",
handler: "myController.downloadCSV",
config: {
policies: [],
auth: false
}
}
];
const routes = {
"content-api": {
type: "content-api",
routes: contentAPIRoutes
},
admin: {
type: "admin",
routes: adminRoutes
}
};
require("exceljs");
const service = ({ strapi }) => ({
getWelcomeMessage() {
return "Welcome to Strapi 🚀";
},
async getDropDownData() {
try {
let excel = strapi.config.get("excel");
let dropDownValues = [];
let array = Object.keys(excel?.config || {});
Object.entries(strapi.contentTypes).forEach(([uid, contentType]) => {
if (contentType?.kind === "collectionType") {
array?.forEach((data) => {
if (uid?.startsWith(data)) {
dropDownValues.push({
label: contentType?.info?.displayName,
value: uid
});
}
});
}
});
dropDownValues.sort((a, b) => a.label.localeCompare(b.label));
console.log("drop", dropDownValues);
return {
data: dropDownValues
};
} catch (error) {
strapi.log.error("Error fetching dropdown data:", error);
Context.throw(500, "internal server error while fetching dropdown data");
}
},
async getTableData(ctx) {
try {
const excel = strapi.config.get("excel");
const uid = ctx.query.uid;
console.log(JSON.stringify(uid));
const limit = parseInt(ctx.query.limit, 10) || 10;
const offset = parseInt(ctx.query.offset, 10) || 0;
if (!uid || !excel?.config[uid]) {
return ctx.badRequest("Invalid content type uid");
}
const query = await this.restructureObject(excel.config[uid], uid, limit, offset);
console.log("query", query);
const response = await strapi.entityService.findMany(uid, query);
const header = [
...excel.config[uid].columns,
...Object.keys(excel.config[uid].relation || {})
];
let where = {};
if (excel.config[uid].locale === "true") {
where = {
locale: "en"
};
}
const count = await strapi.entityService.count(uid, { filters: where });
const tableData = await this.restructureData(response, excel.config[uid]);
return {
data: tableData,
count,
columns: header
};
} catch (error) {
strapi.log.error("Error fetching table data:", error);
ctx.throw(500, "Internal server error while fetching table data");
}
},
async downloadCSV(ctx) {
try {
const excel = strapi.config.get("excel");
const uid = ctx.query.uid;
console.log("hello on downloadCSV");
if (!uid || !excel?.config[uid]) {
return ctx.badRequest("Invalid content type uid");
}
const query = await this.restructureObject(excel.config[uid], uid);
const response = await strapi.entityService.findMany(uid, query);
const csvData = await this.restructureData(response, excel.config[uid]);
console.log("response", response, "csvData", csvData);
const headers = [
...excel.config[uid].columns,
...Object.keys(excel.config[uid].relation || {})
];
const headerRestructure = headers.map(
(element) => element.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ")
);
let csvContent = headerRestructure.join(",") + "\n";
csvData.forEach((row) => {
const csvRow = headers.map((header) => {
const value = row[header] !== void 0 && row[header] !== null ? row[header].toString() : "";
return value.includes(",") ? `"${value}"` : value;
}).join(",");
csvContent += csvRow + "\n";
});
ctx.set("Content-Disposition", "attachment; filename=export.csv");
ctx.set("Content-Type", "text/csv");
return Buffer.from(csvContent);
} catch (error) {
strapi.log.error("Error generating CSV file:", error);
ctx.throw(500, "Internal server error while generating CSV file");
}
},
async restructureObject(inputObject, uid, limit, offset) {
const excel = strapi.config.get("excel");
let filters = {};
if (excel?.config[uid]?.locale === "true") {
filters = {
locale: "en"
};
}
const restructuredObject = {
fields: inputObject.columns || void 0,
populate: {},
filters,
sort: { id: "asc" },
limit,
offset
};
for (const key in inputObject.relation || {}) {
restructuredObject.populate[key] = {
fields: inputObject.relation[key].column
};
}
return restructuredObject;
},
async restructureData(data, objectStructure) {
return data.map((item) => {
const restructuredItem = {};
for (const key of objectStructure.columns) {
if (key in item) {
restructuredItem[key] = item[key];
}
}
for (const key in objectStructure.relation || {}) {
if (key in item) {
const column = objectStructure.relation[key].column[0];
if (item[key] && typeof item[key] === "object") {
if (Array.isArray(item[key]) && item[key].length > 0) {
restructuredItem[key] = item[key].map((obj) => obj[column]).filter(Boolean).join(" ");
} else {
restructuredItem[key] = item[key][column];
}
} else {
restructuredItem[key] = null;
}
}
}
return restructuredItem;
});
}
});
const services = {
service
};
const index = {
bootstrap,
destroy,
register,
config,
controllers,
contentTypes,
middlewares,
policies,
routes,
services
};
export {
index as default
};