大專案中網頁多語系的維護方式
也許在許多專案上我們所說的Multi Language僅有繁體中文、簡體中文和英文,但在比較大型且跨國的專案上,可能會涉及更多的語言,例如:日文、俄文、德文、法文、西班牙文…等等,通常這些軟體內容的翻譯,需要經過更專業的單位來進行,也許這個單位不僅僅需要具備有這些國家的語言能力,也要具備有相當的軟體知識,才能配合當地民情翻譯出正確的文字,這部分往往需要專業的翻譯單位來進行。
而專業的翻譯單位通常並不具有軟體的製作能力,所以在軟體上要如何快速地進行協同作業,就變成一項非常重要的工作,而在許多專案上,我們會讓翻譯單位透過Excel來提供各國語系的翻譯文字,我們則透過軟體進行轉換,將其轉換至軟體能快速讀取的格式,講白一點就是將Excel檔案轉換成XML格式,並提供其他軟體進行讀取。
整體流程會如上圖所示,在拿到一個翻譯社提供所有語系的Excel資料後,我們會進行轉換,將文字轉換成多個XML檔案,並打包成一個ZIP檔讓轉換者進行下載。
今天我們主要來分享上圖藍色部分的處理程序,也就是那一隻轉換程式的結構和做法,我們將轉換程式設計成網頁版本,藉此提升易用性,而轉換程式操作Flow大致如下:
- 使用者上傳檔案(限制僅能上傳Excel檔案)
- 給出ZIP下載連結(提供使用者下載所有語系的XML檔)
操作上非常簡單,僅有上述這兩個步驟,而程式設計上採用JSP架構其運作邏輯如下:
- 檢查上傳檔案的格式、容量及相關資訊
- 擷取Excel中第一張工作表(也可以依照工作表名稱擷取)
- 將Excel中第一列視為語系標題,並當作存檔名稱(例如:English.xml)
- 將剩下來的每一列轉換為該檔案的語系資料,並建立XML檔案
- 將所有建立好的XML檔案進行打包(ZIP)
- 更新頁面產生ZIP檔下載路徑
在該轉換程式中,另外有利用到下述的JAVA Library:
- Apache POI – 處理與解析Excel檔案
- DOM4J – 建立XML檔案
- Apache Commons – 處理檔案上傳
以下是轉換的程式碼:
<%@ page contentType="text/html; charset=UTF-8"%> <%@ page import="java.io.File"%> <%@ page import="java.text.*" %> <%@ page import="java.util.*" %> <%@ page import="java.util.Iterator"%> <%@ page import="java.util.List"%> <%@ page import="org.apache.commons.fileupload.*"%> <%@ page import="org.apache.commons.io.FilenameUtils"%> <%@ page import="java.util.zip.ZipEntry"%> <%@ page import="java.util.zip.ZipOutputStream"%> <%@ page import="java.io.FileInputStream"%> <%@ page import="java.io.FileOutputStream"%> <%@ page import="java.io.IOException"%> <%@ page import="java.io.OutputStreamWriter"%> <%@ page import="java.nio.charset.Charset"%> <%@ page import="org.apache.poi.hssf.usermodel.HSSFRow"%> <%@ page import="org.apache.poi.hssf.usermodel.HSSFSheet"%> <%@ page import="org.apache.poi.hssf.usermodel.HSSFWorkbook"%> <%@ page import="org.dom4j.io.OutputFormat"%> <%@ page import="org.dom4j.io.XMLWriter"%> <%@ page import="org.dom4j.Document"%> <%@ page import="org.dom4j.DocumentHelper"%> <%@ page import="org.dom4j.Element"%> <%! //允許上傳的檔案 String allowedFileTypes = ".xls"; //建立目錄 public void newFolder(String folderPath) { try { String filePath = folderPath; filePath = filePath.toString(); java.io.File myFilePath = new java.io.File(filePath); if (!myFilePath.exists()) { myFilePath.mkdir(); } } catch(Exception e) { System.out.println("建立目錄錯誤"); //e.printStackTrace(); } } // 轉換XLS為XML的主程式 ; 參數1.欲轉換的Excel工作表編號; 參數2.轉換的檔案路徑與檔名; 參數3.XML儲存的檔案路徑; public static String convertSheet(int sheetNumber, String conversionFile, String conversionXMLFilePath) { String convertStatus = "0"; // 輸出轉換狀態 ; 0 是失敗; 1是成功 String conversionXMLFileName = null; // XML檔名 String conversionXMLFile = null; // XML完整路徑與檔名 // 產生儲存XML檔案的資料夾 File file = new File(conversionXMLFilePath); if(!file.exists()){ file.mkdirs(); } // 開始讀取XLS檔案 HSSFWorkbook book = null; try { book = new HSSFWorkbook(new FileInputStream(conversionFile)); } catch (IOException e) { System.out.println("IOException : " + e); } HSSFSheet sheet = book.getSheetAt(sheetNumber); // 打開對應編號的工作表 HSSFRow row = sheet.getRow(0);// 取得工作表的第一列資料 String cell; int totalRows = sheet.getPhysicalNumberOfRows(); // 取得工作表中所有的列數 int totalCol = row.getPhysicalNumberOfCells(); // 取的工作表中所有的欄數 // 開始建立XML檔並將XLS內容建入 for (int j = 1; j < totalCol; j++){ Document document = DocumentHelper.createDocument(); Element root = document.addElement("root"); for (int i = 0; i < totalRows; i++){ row = sheet.getRow(i); try { cell = row.getCell(j).toString(); if(i==0) { conversionXMLFileName = cell; conversionXMLFile = conversionXMLFilePath + conversionXMLFileName + ".xml"; }else { root.addElement("row_" + (i+1)).addCDATA(cell); /* if(sheetNumber == 0) { root.addElement("tag_" + (i-1), cell); }else { root.addElement(xmlKeyboardTitle[(i-1)], cell); } */ } } catch (NullPointerException e) { break; } } File storedFile = new File(conversionXMLFile); if(storedFile.exists()) storedFile.delete(); FileOutputStream fos = null; OutputStreamWriter osw = null; XMLWriter writer = null; try { storedFile.createNewFile(); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); fos = new FileOutputStream(storedFile); osw = new OutputStreamWriter(fos, Charset.forName("utf-8")); writer = new XMLWriter(osw, format); writer.write(document); } catch (IOException e) { System.out.println("IOException : " + e); } finally { try { if(writer != null) writer.close(); if(osw != null) osw.close(); if(fos != null) fos.close(); convertStatus = "1"; } catch (IOException e) { System.out.println("IOException : " + e); } } } return convertStatus; // 回覆轉換狀態 } List<String> filesListInDir = new ArrayList<String>(); public void zipDirectory(File dir, String zipDirName) { filesListInDir = new ArrayList<String>(); try { populateFilesList(dir); //now zip files one by one //create ZipOutputStream to write to the zip file FileOutputStream fos = new FileOutputStream(zipDirName); ZipOutputStream zos = new ZipOutputStream(fos); for(String filePath : filesListInDir){ System.out.println("Zipping "+filePath); //for ZipEntry we need to keep only relative file path, so we used substring on absolute path ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length()+1, filePath.length())); zos.putNextEntry(ze); //read the file and write to ZipOutputStream FileInputStream fis = new FileInputStream(filePath); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) > 0) { zos.write(buffer, 0, len); } zos.closeEntry(); fis.close(); } zos.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } private void populateFilesList(File dir) throws IOException { File[] files = dir.listFiles(); for(File file : files){ if(file.isFile()) filesListInDir.add(file.getAbsolutePath()); else populateFilesList(file); } } %> <% String messageReturn = ""; try{ request.setCharacterEncoding("utf-8"); DiskFileUpload fileUpload = new DiskFileUpload(); List<FileItem> fileItems = fileUpload.parseRequest(request); FileItem fileItem = fileItems.get(0); //原始上傳檔案名稱 String originalFileName = fileItem.getName(); //out.print("originalFileName : " + originalFileName + "<br>"); if (originalFileName != null && !"".equals(originalFileName)) { originalFileName = FilenameUtils.getName(originalFileName); String extension = FilenameUtils.getExtension(originalFileName); //判斷檔案格式是否允許 //out.print("extension : " + extension + "<br>"); if (allowedFileTypes.indexOf(extension.toLowerCase()) != -1) { String filePath = this.getServletContext().getRealPath(request.getRequestURI().substring(request.getContextPath().length())); String savePath = new File(filePath).getParent() + "/upload"; //out.println("savePath = " + savePath + "<br>"); newFolder(savePath); String savePathAndName = savePath + "/" + originalFileName; //out.print(savePathAndName); File f = new File(savePathAndName); if(!f.exists()){ f.createNewFile(); } fileItem.write(f); //messageReturn += "File path : " + savePath + "<br>"; String xmlSavePath = savePath + "/xml/"; //messageReturn += "xmlSavePath : " + xmlSavePath + "<br>"; if("1".equals(convertSheet(0, savePathAndName , xmlSavePath))){ messageReturn += "File converted successfully.<br>"; }else{ messageReturn += "File conversion failed.<br>"; }; /* xmlSavePath = savePath + "/xml/keyboard/"; if("1".equals(convertSheet(1, savePathAndName , xmlSavePath))){ messageReturn += "Keyboard sheet conversion succeeded.<br>"; }else{ messageReturn += "Keyboard sheet conversion fail.<br>"; }; */ java.io.File myDelFile = new java.io.File(savePath + "/All.zip"); myDelFile.delete(); zipDirectory(new File(savePath + "/xml/"), savePath + "/All.zip"); messageReturn += "<a href='upload/All.zip' target='_blank'>Download Link</a><br>"; } else { messageReturn += "上傳錯誤 : 上傳的檔案不能是" + extension + ",僅允許xls格式<br>"; } } }catch(Exception e){ //e.printStackTrace(); } %> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>AIOT CC Multi-Language Convertion Tool</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <style> *{ font-family: 微軟正黑體; } h2{ text-align: center; } .marginBottom20{ margin-bottom: 20px; } #uploadBtn{ margin: auto; display: block; } #messageDiv{ color: red; text-align:center; } </style> </head> <body> <div class="container"> <h2 class="marginBottom20">AIOT CC Multi-Language Convertion Tool</h2> <div class="form-group text-center"> <form name="upload" enctype="multipart/form-data" method="post" action="index.jsp" onsubmit="return check_select()"> <input type="file" name="file" id="file" size="60" maxlength="20" placeholder="*.xls" class="marginBottom20"> <input id="uploadBtn" type="submit" value="轉換" class="btn btn-primary"> </form> </div> <div id="messageDiv"><% out.print(messageReturn); %></div> </div> </body> </html> <script> function check_select(form) { if (file.value == "") { alert("請選擇檔案"); return false; } else { // document.getElementById("uploadBtn").disabled = true; //document.getElementById("msgDiv").innerHTML = "檔案上傳中,請稍候"; return true; } } </script>
If you can’t afford your complete meeting, it is an inspo to get the inexpensive particular person items on Amazon and combine them yourself!
промокод изи дроп 50 [url=izi-drop-promokod.ru]промокод изи дроп 50[/url] .
sweet bonanza guncel sweet bonanza yorumlar sweet bonanza kazanma saatleri
Up till that time, the only other joyful church season was the fifty days between Easter Sunday and Pentecost.
en kazancl? slot oyunlar?: guvenilir slot siteleri – slot siteleri
блекспрут онион – blacksprut официальный сайт ссылка, blacksprut onion зеркало
промокоды изи дроп 100 процентов промокоды изи дроп 100 процентов .
blacksprut зеркало официальный – blacksprut зеркала, blacksprut официальная ссылка
как найти blacksprut – blacksprut com зеркало сайта, bs2site at зеркала
One secure various to SSO is a dedicated password supervisor comparable to 1Password.
http blacksprut onion – blacksprut ссылка bs2tor nl, bs2best at регистрация
casino bahis siteleri: canl? casino siteleri – Casino Siteleri
BreakingBad forum chemistry – bb, breakingbad forum
View all of the most shorted stocks.
blacksprut официальный сайт – блекспрут bs2web, блекспрут бс сайт bs site biz
deneme bonusu veren casino siteleri: casino bahis siteleri – canl? casino siteleri
breaking bad forum – BreakingBad forum chemistry, BBGate Free Sample
What’s Everyone Talking About Asbestos Attorneys This Moment Mesothelioma Lawyer
промо изи дроп промо изи дроп .
Welcome to Extra Finance
At Extra Finance, we believe in empowering individuals and businesses with the tools they need to manage their finances more effectively. Whether you are looking to save smarter, invest wisely, or simply manage your expenses better, Extra Finance offers a range of solutions to help you achieve your goals.
extra finance
Why Choose Extra Finance?
Extra Finance stands out for its commitment to customer satisfaction and cutting-edge financial tools. Here are a few reasons why you should consider us:
Comprehensive Financial Solutions: From personal savings plans to business investment opportunities, we cover a wide spectrum of financial needs.
User-Friendly Platform: Navigate through your financial options with ease thanks to our intuitive and straightforward interface.
Expert Guidance: Our team of experienced financial advisors is always ready to assist you in making the best financial decisions.
Services Offered by Extra Finance
Extra Finance is committed to providing a diverse range of services that cater to different financial needs:
Personal Finance Management: Tools and advice to help individuals manage their personal finances, set budgets, and save for the future.
Investment Solutions: Personalized investment portfolios to help you grow your wealth according to your financial objectives.
Loan Products: Flexible and competitive loans tailored to meet your needs.
Retirement Planning: Strategic planning services to ensure your retirement is financially secure and comfortable.
Getting Started with Extra Finance
To join Extra Finance, simply create an account on our platform and begin exploring the numerous financial opportunities available to you. With just a few clicks, you can take control of your financial future.
Remember, financial success is not just about making the right decisions today but about planning for tomorrow. Let Extra Finance be your partner on this journey to financial freedom!
bbgate.com – bb gate, BreakingBad forum chemistry
kraken маркетплейс ссылка – kraken tor ссылка bazaonion vip, кракен официальный сайт
http://casinositeleri25.com/# Canl? Casino Siteleri
kraken маркетплейс ссылка – https kraken20 at не работает, kraken20 at kraken19at online
Listing of Ok-pop songs on the Billboard Japan Scorching a hundred is a compilation of weekly chart information for Okay-pop music published on the Billboard Japan Hot 100 chart by the Billboard charts, and reported on by Billboard Okay-City, a web based Billboard column.
рабочая ссылка на blacksprut – bs2web at, blacksprut onion ссылка
https://slotsiteleri25.com/# en cok kazand?ran slot oyunlar?
Welcome to EtherFi: Revolutionizing Financial Transactions
In the dynamic world of digital finance, EtherFi stands out as a revolutionary platform designed to reshape how you manage transactions and investments. Understanding this cutting-edge platform can provide you with the tools necessary for financial success in the digital age.
ether.fi
What is EtherFi?
EtherFi is a robust platform built on advanced blockchain technology, offering secure, efficient, and transparent financial solutions. It leverages the power of Ethereum to facilitate various transactions, ensuring that users have access to a decentralized and trustworthy financial ecosystem.
Key Features of EtherFi
Decentralized Finance (DeFi): Enjoy the benefits of financial services without the need for traditional banking institutions.
Fast and Secure Transactions: Built on the Ethereum blockchain, EtherFi ensures that your transactions are both rapid and secure.
Low Transaction Fees: Reduce costs associated with financial transactions compared to traditional methods.
User-Friendly Interface: Whether you’re a seasoned investor or a newcomer, EtherFi’s platform is designed for ease of use.
Investment Opportunities with EtherFi
EtherFi offers a range of opportunities for investors looking to diversify their portfolios with blockchain assets. By utilizing smart contracts and decentralized applications, investors can securely manage and grow their digital assets with minimal risk.
Why Choose EtherFi?
As the world moves towards digital transformation, choosing a platform that can keep up with technological advancements is crucial. EtherFi not only provides an innovative approach to financial management but also ensures top-tier security, making it a preferred choice for digital finance enthusiasts.
Getting Started with EtherFi
Sign Up: Create an account on the EtherFi platform to begin your journey in digital finance.
Link Your Wallet: Connect your Ethereum wallet to start transacting seamlessly.
Explore Features: Navigate through the array of features available to optimize your investment strategies.
Invest & Transact: Utilize the platform to make informed investment decisions and complete secure transactions.
Overall, EtherFi offers a comprehensive and secure solution for anyone looking to embrace the future of finance. By integrating blockchain technology with everyday financial activities, users can enjoy unparalleled efficiency and effectiveness in their transactions and investments. Start your financial revolution with EtherFi today!
kraken биржа – kraken маркетплейс ссылка, kraken маркетплейс ссылка
Renzo Protocol: Secure Blockchain Innovation
Discover the Renzo Protocol: Revolutionizing Blockchain
The Renzo Protocol represents a significant advancement in the blockchain technology landscape. It offers a secure and efficient platform for decentralized applications, setting a new standard in the industry.
renzo ezeth
Key Features of the Renzo Protocol
The Renzo Protocol is designed to enhance the functionality and security of blockchain applications. Here are some of its key features:
High Security: Utilizing advanced encryption methods to protect user data and transactions.
Scalability: Capable of handling a large number of transactions per second, making it ideal for various applications.
Decentralization: Ensures that no central authority controls the network, maintaining the core principles of blockchain.
Interoperability: Seamlessly connects with other blockchain networks and systems.
Benefits for Developers and Businesses
The Renzo Protocol offers numerous benefits for both developers and businesses looking to leverage blockchain technology:
Reduced Costs: By automating processes and cutting out intermediaries, businesses can significantly reduce operational costs.
Improved Transparency: Every transaction is recorded on the blockchain, providing an immutable and transparent ledger.
Enhanced Trust: The secure nature of the protocol builds trust among users and stakeholders.
Development Support: Provides extensive documentation and tools to help developers create robust applications.
Getting Started with the Renzo Protocol
To start utilizing the Renzo Protocol, follow these simple steps:
Visit the Renzo Protocol website and create an account.
Access the API documentation and development tools.
Join the Renzo community to connect with other developers and experts.
Start building and deploying your decentralized applications.
The Renzo Protocol is not only a beacon of security and efficiency in the blockchain space but also a catalyst for innovation. Whether you are a developer, a business leader, or simply interested in cutting-edge technology, the Renzo Protocol offers the tools and community support needed to drive your projects to success. Embrace the future with the Renzo Protocol and harness the full potential of blockchain technology.
Renzo Protocol Restaking Guide
Renzo Protocol Restaking: A Comprehensive Guide
Renzo Protocol has revolutionized the method through which investors can maximize their crypto assets, particularly through the innovative concept of restaking. This guide will explore the benefits, processes, and strategies of restaking within the Renzo Protocol ecosystem, helping you make the most out of your investments.